Last updated March 4, 2016. Created on November 16, 2011.
Edited by indytechcook, tz_earl, drupalshrek, batigolix. Log in to edit this page.

The EntityFieldQuery API lets you fetch information about entities (nodes, users, taxonomy terms et cetera) from Drupal without actually building SQL queries.

EntityFieldQuery is a class 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. and the test cases in modules\simpletest\tests\entity_query.test are the authoritative documentation for EntityFieldQuery. The class itself "EntityFieldQuery" is in includes/ 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.

$query = new EntityFieldQuery();

$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'article')
  ->propertyCondition('status', NODE_PUBLISHED)
  ->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')
  • revision_id.
    • value examples: 3,4,52,342
    • operator examples: =, <, >, != for integer values and 'IN' and 'NOT IN' for arrays of values.
    • $query->entityCondition('revision_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', NODE_PUBLISHED)
  • 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.

->fieldOrderBy($field, $column, $direction = 'ASC')

  • field. Notice again that the first parameter, field_photo, has the prefix "field_data_" removed. That is, if you look in the database, you would see a table called field_data_field_photo, but for this parameter you remove the prefix "field_data_" and just keep the "field_photo" suffix of the table name.
  • column. Notice again that in the database, in the field_data_field_photo table, you would find a column called field_photo_value, but here you must remove the prefix "field_photo_" and just keep the field title as "value".

->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.


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));


The $value and $operator parameters of entityCondition, propertyCondition, and fieldCondition behave the same. The $operator values depend on the $value format as summarized in

Random ordering

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

function mymodule_superblock() {
  $query = new EntityFieldQuery();
  $result = $query
    ->entityCondition('entity_type', 'node')
    ->fieldCondition('field_categories', 'tid', array('12','13'), 'IN')
    ->propertyCondition('status', NODE_PUBLISHED)

and then :

function mymodule_query_random_alter($query){

See : hook_query_TAG_alter

Example taxonomy term query

This example returns the taxonomy term ids of the terms in the Tags vocabulary.

function connect_country_fetch_countries() {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'taxonomy_term')
  ->entityCondition('bundle', array('tags'))
  $result = $query->execute();
  $tids = array_keys($result['taxonomy_term']);
  return $tids;

What to feed to EntityQuery?

These functions can help you get a list of defined entities and fields that you can then feed to your queries:

 dpm(entity_get_info()); //gets a list of all defined entities
dpm(field_info_fields()); //gets a list of all defined fields


As explained on stackexchange you can debug entity field queries by implementing hook_query_alter() and using the dpm function from devel:

function CUSTOMMODULE_query_alter($query) {
  if ($query->hasTag('efq_debug') && module_exists('devel')) {
    dpm((string) $query);

When you have added this function to your custom module you can extend the query with addTag('efq_debug'), e.g. as follows:

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');

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


Other resources

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


TuWebO’s picture

There is a
that will bypass access checkings, here is the documentation

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.

RavindraSingh’s picture

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

jjonj’s picture

You should look at node_load!node!node.module/function/node_...
with that you can use the NID to get the full node.

RavindraSingh’s picture

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', '=')
Anurag Ashok’s picture

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.

RavindraSingh’s picture

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

earwax’s picture

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. :(

johnbarclay’s picture

this example solves the problem of loading all the nodes and getting the data.

use entity_load() or node_load_multiple()

e0ipso’s picture

OwilliwO’s picture

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..

$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 ?

TanvirAhmad’s picture

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


ivanjaros’s picture

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').

ymakux’s picture

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

natemow’s picture

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, uses this exclusively for all Views required!

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

danharper’s picture

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

There is the created field in my entitytype table.


Scott Falconer’s picture

Something like this should work:

  // 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, '>'); 
RavindraSingh’s picture

@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

 $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'my_entity')
   $query->propertyOrderBy('created', 'DESC');
danharper’s picture

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.

$instance = array('start' => 1370214001, 'end' => 1370905199);

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


tcalin’s picture

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'], '=')

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.

dobe’s picture

I am not sure if it is the same issue or not. But I had the similar issue when I didn't use $result = $query->execute(); to execute the query.

selvamkf’s picture

I used a query like this,

  $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?

danielphenry’s picture


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)
samsterlin’s picture


Thanks alot It works for me.

This code is displaying a last 30 days records.

    $query = new EntityFieldQuery();
    $query->entityCondition('entity_type', 'node')
               ->entityCondition('bundle', 'TYPE')
               ->propertyCondition('created', array(REQUEST_TIME- 60 * 60 * 24 * 30, REQUEST_TIME ), "between")
               ->propertyOrderBy('created', 'DESC');
   $result = $query->execute();
spoetnik’s picture

Unlike db_query(), EntityFieldQuery doesn't support Union()

Any thoughts on a workaround? Like merge the resulting arrays, but keep the overall order of the array?

bhupendra_kanojiya’s picture

When I am using not null(!=) it's working, but not working for fetch the null value

$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
->entityCondition('bundle', $content_type)
->propertyCondition('status', 1)
->fieldCondition('field_suggested_tags', 'tid', $child_term)
->fieldCondition('field_close_date', 'value','NULL','=')

sebto’s picture

This class is great. I wrote a tutorial to use EntityFieldQuery in my blog for persians.

fuerst’s picture

Use nicedpq($query) instead of dpm((string) $query) to get a nice formatted debug output.
You need to install the Nice DPQ module for that.

SlyK’s picture

In my project I'm using EntityFieldQuery alot to get some entities with given conditions, but working with resulting array of execute() function - is boring and makes code dirty IMHO. So I created helper class used only to load entities. Most of the time result is self describing one-liners instead of variables mess. I know it not covers all posibilities of EntityQuery, but 90% of my usage of it is loading Entities with some conditions.

 * Easily load entities with power of EntityFieldQuery
 * Usage example:
 * $country = (new EntityLoadQuery('country'))->propertyCondition('city_tid', 88)->loadSingle();
 * @author Kirill Kuzmitskyy (
class EntityLoadQuery extends EntityFieldQuery {

	 * @param string $entity_type tell the type of the entity to load
	public function __construct($entity_type) {
		$this->entityCondition('entity_type', $entity_type);

	 * @param $entity_type tell the type of the entity to load
	 * @return EntityLoad
	public static function query($entity_type) {
		return new EntityLoad($entity_type);

	 * @return array of loaded entities keyed by Names or IDs
	public function load() {
		$eqResult = $this->execute();
		foreach ($eqResult as $entity_type=>$keyedArray)
			return (module_exists('entity'))
				? entity_load_multiple_by_name($entity_type, array_keys($keyedArray))
				: entity_load($entity_type, array_keys($keyedArray));
		return array();

	 * @return object one loaded entity of given type
	public function loadSingle() {
		$ents = $this->load();
		return reset($ents);

	 * @return array of Names or IDs of the entities matching query
	public function loadIDs() {
		$eqResult = $this->execute();
		$eqResult = reset($eqResult);
		return ($eqResult) ? $eqResult : array();


As the result, instead of doing like this:

$result = (new EntityFieldQuery())
                   ->propertyCondition('city_tid', 55)

if (isset($result['country'])) {
  $news_items_ids = array_keys($result['country']);
  $entities = entity_load('country', $news_items_nids);
  $country = reset($entities);

I have this code:

$country = EntityLoad::query('country')->propertyCondition('city_tid', 88)->loadSingle();

I think it's more readable and less non-business logic in code. Hope someone will like it too :) And correct me if I'm doing something wrong with such approach.

lipinponmala007’s picture

Interesting...This will work..but I think the real power of the original one is the ability to keep the query with out executing add the fields and exicute them at the time we need. This is how I observe it ... :)

ehsankhfr’s picture


nithinkolekar’s picture

Is there a way to typecast while checking condition?
fieldCondition('field_total_price', 'value',$total, '!=')

if stored value of field field_total_price is 1000.00 and $total is 1000 could it be possible to typecast the value(in this case int or float) while comparing?

Mujtaba Ahmad’s picture

Child node has a entity reference field. and i want to get parent node from child node, and proper way to do this ?