如何使用EntityFieldQuery
如何使用 EntityFieldQuery
EntityFieldQuery 是 Drupal 7 中新增的一个类,允许利用指定条件获取符合条件的实体。查询条件可以基于属性,字段值以及一些其他的通用的实体元数据。他的语法非常紧凑和实用,而且这一功能由Drupal核心提供,无需另外安装其他模块。
API 手册以及 modules\simpletest\tests\entity_query.test 中的测试用例,可以作为 EntityFieldQuery 的权威文档。”EntityFieldQuery” 类包含于 includes/entity.inc中。本文仅作为一个入门的简介供读者参考。
建立一个查询
下面是一个简单的查询,用来查询所有包含今年教员照片的所有文章。下面的最后五行代码,$result
是一个联合数组,第一个键是实体类型,第二个键是实体编号(例如$result['node'][12322] = Node数据
),注意如果结果集为空,则其中不会有 ‘node’ 键,因此需要用 isset来检查,这里介绍了这种做法的来由。
<?php
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'article')
->propertyCondition('status', 1)
->fieldCondition('field_news_types', 'value', 'spotlight', '=')
->fieldCondition('field_photo', 'fid', 'NULL', '!=')
->fieldCondition('field_faculty_tag', 'tid', $value)
->fieldCondition('field_news_publishdate', 'value', $year . '%', 'like')
->fieldOrderBy('field_photo', 'fid', 'DESC')
->range(0, 10)
->addMetaData('account', user_load(1)); // Run the query as user 1.
$result = $query->execute();
if (isset($result['node'])) {
$news_items_nids = array_keys($result['node']);
$news_items = entity_load('node', $news_items_nids);
}
?>
->entityCondition($name, $value, $operator = NULL)
entityConditions 是绝大多数实体类在 DrupalDefaultEntityController 类都应该支持的查询条件。
entity_type
- 取值举例:’node’, ‘taxnonomy_term’, ‘comment’, ‘user’, ‘file’
- 操作符举例:不需要
- $query->entityCondition(‘entity_type’, ‘node’)
bundle(comment实体类型不支持)
- 取值举例:’artical’, ‘page’
- 操作符举例:’=’ 字符串,或者 ‘IN’ 数组
$query->entityCondition('bundle', 'article')
revision_id
- 取值举例:3, 4, 52, 342
- 操作符举例:整数
=, <, >, !=
,数组可以使用’IN’和’NOT IN’ $query->entityCondition('revision_id', $revision_id, '=')
entity_id 例如 node id
- 取值举例:3,4,52,342
- 操作符举例:整数
=, <, >, !=
,数组可以使用 ‘IN’ 和 ‘NOT IN’ $query->entityCondition('entity_id', array(17, 21,422), 'IN')
->propertyCondition($name, $value, $operator = NULL)
这些条件针对各种实体实现,例如Node, user, comment等。基本上是映射到entity自身的数据表字段中。例如node, users, comment, file_managed
, taxonomy_term_data
类似的表。用grep/search来查找”Implements hook_entity_info()“能查到实体对应的数据表。
- status (nodes) 例如:
->propertyCondition('status', 1)
- type (nodes) 例如:
->propertyCondition('type', array('article', 'page', 'blog'))
- uid (nodes) 例如:
->propertyCondition('uid', $uid)
- uri (media) 例如:
->propertyCondition('uri', '%.jpg', 'LIKE')
- type (media) 例如:
->propertyCondition('type', 'image');
这类条件针对实体的字段来执行。
比如要查找 article node 的 body 字段:->fieldCondition('body', 'value', 'A', 'STARTS_WITH')
- 字段名称:一般来说,一个表如果叫
field_data_body
,实际的字段名就是 body。这个配置保存在field_config_instance
表中。 - 列:这是在数据库中对应的列的列名称去掉前缀的部分。body字段的数据库列为
body_value
,body_summary
,body_format
以及 language。真正使用时会使用 value, summary, format 以及 language。 类似的,image 字段会使用 fid, alt 以及 title 作为列名;entity 引用字段会使用target_id
以及target_type
作为列名。
->propertyOrderBy($column, $direction = 'ASC')
不是对所有属性都生效的。
http://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3Arange/7
限制查询结果集的范围。
->count()
设置查询只返回数量,例如:
$count = $query->count()->execute();
->addMetaData($key, $object)
在查询中加入其他元数据。因为 EntityFieldQuery 的 fieldCondition 会使用当前用户的权限进行查询,这通常不是我们想要的结果,所以这个方法的一个重要的用途就是用其他用户的身份进行查询,可以在这里使用1号用户进行查询:
$query->addMetaData('account', user_load(1));
随机排序
最简单的随机排序方法就是添加一个 tag,然后进行一次 alter。
<?php
function mymodule_superblock() {
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', 'node')
->fieldCondition('field_categories', 'tid', array('12','13'), 'IN')
->propertyCondition('status', 1)
->addTag('random')
->range(0,5)
->execute();
}
?>
接下来做 alter
<?php
function mymodule_query_random_alter($query){
$query->orderRandom();
}
?>
排错
根据在 stackexchange 的内容,可以实现 hook_query_alter() 结合 devel的dpm ,对实体字段查询过程进行排错。
<?php
function CUSTOMMODULE_query_alter($query) {
if ($query->hasTag('efq_debug') && module_exists('devel')) {
dpm((string) $query);
dpm($query->arguments());
}
}
?>
当你往自己的模块中加入了这个函数,就可以利用addTag('efq_debug')
来扩展这个查询:
<?php
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('efq_debug');
->execute();
?>
相关资源
代码实例
- modules\simpletest\tests\entity_query.test中的EntityFieldQuery测试。
- 在核心和其他模块中利用grep/search搜索
new EntityFieldQuery()
。
文章和教程
- 没有 views 的 Energy.gov
- Drupal.org 的相关论题
- EntityFieldQuery: Let Drupal Do The Heavy Lifting (Pt 1)
- EntityFieldQuery: Let Drupal Do The Heavy Lifting (Pt 2)
- EntityFieldQuery中的OR查询
- 从一个实体或节点中只获取一个字段