欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

如何使用EntityFieldQuery

shiping1 的头像
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_managedtaxonomy_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');

->fieldCondition($field, $column = NULL, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL)

这类条件针对实体的字段来执行。

比如要查找article node的body字段:->fieldCondition('body', 'value', 'A', 'STARTS_WITH')

  • 字段名称:一般来说,一个表如果叫field_data_body,实际的字段名就是body。这个配置保存在field_config_instance表中。
  • 列:这是在数据库中对应的列的列名称去掉前缀的部分。body字段的数据库列为body_value,body_summarybody_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();
}
?>

参考:hook_query_TAG_alter

排错

根据在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();
?>

来自  http://drupal.fleeto.us/translation/how-use-entityfieldquery
普通分类: