Last updated September 10, 2013. Created by johnbarclay on November 16, 2011.
Edited by anniegreens, targoo, arithmetric, batigolix. Log in to edit this page.

EntityFieldQuery is a class, new to Drupal 7, that allows retrieval of a set of entities based on specified conditions. It allows finding of entities based on entity properties, field values, and other generic entity metadata. The syntax is really compact and easy to follow, as well. And, best of all, it's core Drupal; no additional modules are necessary to use it.

http://api.drupal.org/api/drupal/includes--entity.inc/class/EntityFieldQ... and the test cases in modules\simpletest\tests\entity_query.test are the authoritative documentation for EntityFieldQuery. The class itself "EntityFieldQuery" is in includes/entity.inc. This article is just jumpstart type documentation.

Creating A Query

Here is a basic query looking for all articles with a photo that are tagged as a particular faculty member and published this year. In the last 5 lines of the code below, the $result variable is populated with an associative array with the first key being the entity type and the second key being the entity id (e.g., $result['node'][12322] = partial node data). Note the $result won't have the 'node' key when it's empty, thus the check using isset, this is explained here.

<?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 are conditions most types of entity classes should support and are in DrupalDefaultEntityController class.

  • entity_type
    • value examples: 'node', 'taxonomy_term', 'comment', 'user', 'file'
    • operator examples: operator disregarded
    • $query->entityCondition('entity_type', 'node')
  • bundle. (not supported in comment entity types)
    • value examples: 'article', 'page'.
    • operator examples: '=' for strings and 'IN' for arrays.
    • $query->entityCondition('bundle', 'article')
  • revisions_id.
    • value examples: 3,4,52,342
    • operator examples: =, <, >, != for integer values and 'IN' and 'NOT IN' for arrays of values.
    • $query->entityCondition('revisions_id', $revision_id, '=')
  • entity_id. e.g. node id
    • value examples: 3,4,52,342
    • operator examples: =, <, >, != for integer values and 'IN' and 'NOT IN' for arrays of values.
    • $query->entityCondition('entity_id', array(17, 21,422), 'IN')

->propertyCondition($name, $value, $operator = NULL)

These conditions are specific to each entity implementation such as node, user, comment, etc. and generally map to the columns in the database where the entity itself is stored. e.g. node, users, comment, file_managed, taxonomy_term_data, etc tables. A grep/search for "Implements hook_entity_info()" will show code indicating the name of the entity's base table.

  • status (nodes). e.g. propertyCondition('status', 1)
  • type (nodes). e.g. ->propertyCondition('type', array('article', 'page', 'blog'))
  • uid (nodes) .e.g. ->propertyCondition('uid', $uid)
  • uri (media) .e.g. ->propertyCondition('uri', '%.jpg', 'LIKE')
  • type (media) e.g. ->propertyCondition('type', 'image');

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

These conditions are specific to a field implementation.

Looking at the body field in the article node type, a field condition would look like this:
->fieldCondition('body', 'value', 'A', 'STARTS_WITH')

  • field name. Though the field table in the database is named 'field_data_body', the actual field name is 'body'. This is in the field_config_instance table.
  • column. This is the column in the database that should be matched, with field name prefix removed. For body field, the database columns are: body_value, body_summary, body_format, and language. 'value', 'summary', 'format', and 'language' are the actual arguments you would use.
    Likewise an image field would use 'fid', 'alt', and 'title' as column names; an entity reference field would use 'target_id' and 'target_type' as column names.

->propertyOrderBy($column, $direction = 'ASC')

does not work on all properties.

->range($start = NULL, $length = NULL)

Restricts a query to a given range in the result set.

->count()

Sets the query to be a count query only, i.e.

$count = $query->count()->execute();

->addMetaData($key, $object)

Adds additional metadata to the query. One important usage of this method is to run the query as another user, since EntityFieldQuery's fieldCondition will take current user's permission into account, this is not always the desired result, to run the query as for example user 1, use the following code:

$query->addMetaData('account', user_load(1));

Operators

The $value and $operator parameters of entityCondition, propertyCondition, and fieldCondition behave the same. The $operator values depend on the $value format as summarized in http://api.drupal.org/api/drupal/includes--entity.inc/function/EntityFie...

Selected Resources

Code Examples

  • Tests for EntityFieldQuery are in core in modules\simpletest\tests\entity_query.test
  • grep/search drupal code base for "new EntityFieldQuery()" in core and contrib will find additional examples

Articles

Other resources

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

A problem was reported for this page:
http://drupal.org/node/1434094

The easiest way for to order randomly is to add a tag and do an alter on it:

<?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();
}
?>

and then :
<?php
function mymodule_query_random_alter($query){
   
$query->orderRandom();
}
?>

See : hook_query_TAG_alter

There is a
addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
that will bypass access checkings, here is the documentation http://drupal.org/node/1597378

Maybe in some cases could be good use this tag instead of running the query as user 1, but we should know what we are doing, since we are bypassing all access checkings.

Visit my drupal site at: www.viajesdesorganizados.com (Disorganized Trips!)

I have used below mentioned example of EntityFieldQuery. it returns ony 3 fields.

1. Node Id
2. Type
3. Title

What i have to change in this query to get all columns with CCK fields.

$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')
->range(0, 10)
->addMetaData('account', user_load(1)); // Run the query as user 1.

$result = $query->execute();

You should look at node_load
http://api.drupal.org/api/drupal/modules!node!node.module/function/node_...
with that you can use the NID to get the full node.

node_load() does not add conditions for cck fields. wheather EntityFieldQuery query support for applying conditions like

->propertyCondition('status', 1)
->fieldCondition('field_news_types', 'value', 'spotlight', '=')

Use EntityFieldQuery first. You will get a list of node ids of all nodes that match the condition.

then use $node = node_load();
and in $node you will have all the field values.

node_load() loads all the data which i don't want i want some specific fields.

Yeah, with node_load(), it's all or nothing. Otherwise, you can write your own SQL query with tons of JOINS, which is what I have done. :(

this example solves the problem of loading all the nodes and getting the data. http://treehouseagency.com/blog/tim-cosgrove/2012/02/16/entityfieldquery...

use entity_load() or node_load_multiple()

Application Developer University of Illinois Office of Communications for Enrollment Management, johnbarclay.com

I actually work on a Drupal project, with several nodes existing. And I create a module which add a date field to all this nodes (to delay publication in this case). I want to get all nodes that don't have this delayed publication field, just to set it with a default value in a bulk operation for example..

<?php
$efq
= new EntityFieldQuery();
$efq->entityCondition('entity_type', 'node')
    ->
propertyCondition('type', 'article')
   
// doesn't work because field isn't set yet at this moment
   
->fieldCondition('delayed_publication', 'value', NULL);
?>

Any idea ?

Try with node load to see if field is in array or not for that node.

t@n

This doesn't work form me:
->fieldCondition(field_name, field_column, 'NULL', '!=')

I had to use:
->fieldCondition(field_name, field_column, 'NULL', 'IS NOT NULL').

I think it should be "<>" instead of '!='

I tried $query->__toString() to get the resulting SQL. But this method seems not to be available at EntityFieldQuery. So, how can I get the generated sql?

Devel module had db_queryd in D6 version, there should be something similar/the same in D7 version too.

Yep. Unfortunately it's not that easy. I found a solution here:
http://drupal.stackexchange.com/questions/36542/debug-entityfieldquery

Hoping this helps those new to EFQ...simple wrapper class that builds your query based on keyed array params, then returns data in various formats (e.g. renderable array, entity, entity_id). Very much inspired by the related articles on this page. Our new distro (Totem, http://drupal.org/project/totem) uses this exclusively for all queries...no Views required!

http://drupalcode.org/project/totem.git/blob_plain/HEAD:/modules/feature...

This class could probably stand some improvement, so any feedback, patches, etc. are very welcome (preferably in that project's issue queue).

How can I filter by the created date of an entity type?

There is the created field in my entitytype table.

Thanks

Something like this should work:

<?php
 
// Timestamp for ten minutes ago
 
$time_since = time() - 600;
 
$query = new EntityFieldQuery();
 
$query->entityCondition('entity_type', 'my_entity')
 
// Filter by items created since timestamp (eg. in the last 10 minutes).
   
->propertyCondition('created', $time_since, '>');
?>

@Scott Falconer gives right answer but for condition fields. and you want to filter all data with their created date.
We can also use propertyOrderBy

<?php
$query
= new EntityFieldQuery();
 
$query->entityCondition('entity_type', 'my_entity')
  
$query->propertyOrderBy('created', 'DESC');
?>

I think my question was badly worded, I didn't want to filter rather I wanted results between two dates I used the following.

I actually used it liked this, where the instance is an array that holds a timstamp.

<?php
$instance
= array('start' => 1370214001, 'end' => 1370905199);
$query = new EntityFieldQuery();
 
$query->entityCondition('entity_type', 'my_entity')
   ->
propertyCondition('created', array($instance['start'], $instance['end']), 'BETWEEN');
?>

Dan

I have the following code

$node_query = new EntityFieldQuery();
$nodes = $node_query->entityCondition('entity_type', 'node')
          ->entityCondition('bundle', 'stm_emploi')
          ->fieldCondition('field_stm_emploi_extid', 'value', $stmjob['id'], '=')
          ->execute();

These lines should return all nodes of type stm_emploi that have a certain value for field_stm_emploi_extid field. Ideally it should return only one node since field_stm_emploi_extid contains unique values. Well, after someone deleted nodes directly from the node table, the query still returns the nid for those nodes (there are some orphaned rows in field_data_field_stm_emploi_extid table). It does not make a join between the node table and the field's table. The solution was to get back using db_select.

I used a query like this,

<?php
  $query
->entityCondition('entity_type', 'node')
    ->
entityCondition('bundle', 'TYPE')
    ->
entityCondition('entity_id', $already_processed, "NOT IN")
    ->
propertyCondition('created', array(REQUEST_TIME- 60 * 60 * 60 * 60, REQUEST_TIME ), "between")
    ->
propertyOrderBy('created', 'DESC')
    ->
range(0, 25)
?>

when $already_processed is empty array, it returned no results, while $already_processed=array(0), it returned all results as expected. Is it a bug when entity_id with NOT IN condition?

selvamkf,

One of the purposes of using object to query is you can edit them conditionally a lot easier. Try setting up your code like this:

  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'TYPE');
  if (!empty($already_processed)) {
    $query->entityCondition('entity_id', $already_processed, "NOT IN")
  }
  $query->propertyCondition('created', array(REQUEST_TIME- 60 * 60 * 60 * 60, REQUEST_TIME ), "between")
    ->propertyOrderBy('created', 'DESC')
    ->range(0, 25)