7

I have created a content type 'customer' in which I have a field collection named 'field_group'. The field collection has 2 fields namely:

  1. Title
  2. Name

The Customer content type and group field collection are of entity type 'node' and the 2 fields in the group are of entity type 'field_collection_item'. I want to query the database to get the values of the fields in the group for this particular content type. I used to following query to get the field values of the group.

    $query = new EntityFieldQuery();

    $query->entityCondition('entity_type', 'field_collection_item')
          ->entityCondition('bundle', 'field_group');

    $result = $query->execute();

$nodes = entity_load('field_collection_item', array_keys($result['field_collection_item'])); 

But the above entityfieldquery retrieves all the values of entity type field_collection_item. But I want only the values of content type 'customers'. Can anyone tell me what's wrong with the above query?

2 Answers 2

12

An EntityFieldQuery can only refer to one type of entity, it cannot represent any relationships between entities. If the entity_type in your query is a field_collection_item, then that's the type of entity that the query will return. The EntityFieldQuery has no concept of the fact that your field collections are related to nodes, or anything else for that matter.

To get the entities related to the field collections you'll have to run another EntityFieldQuery. I haven't used field collection before but I would guess the logic would look something like this:

$query = new EntityFieldQuery;
$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'customer')
  ->fieldCondition('field_name_of_collection_field', 'name_of_field_collection_column', array_keys($result['field_collection_item']));

There are things that need to be changed in that code (the name of your field collection field, the column name for the field collection relationship) but it should get you started.

Actual example of the two-query approach:

function get_species_country($id_country) {
    $inner = new EntityFieldQuery();
    $inner_r = $inner->entityCondition('entity_type', 'field_collection_item')
                     ->fieldCondition('field_species_country', 'target_id', $id_country, '=')
                     ->execute();
    if(!empty($inner_r['field_collection_item'])) {
        $keys = array_keys($inner_r['field_collection_item']);
        $query = new EntityFieldQuery();
        $species_r = $query->entityCondition('entity_type', 'node')
                      ->entityCondition('bundle', self::$bundle)
                      ->fieldCondition('field_species_countries', 'value', $keys)
                      ->execute();
        if(!empty($species_r['node'])) {
            $ret = node_load_multiple(array_keys($species_r['node']));
        }
    }
    return $ret;
}

In the example above:

  • field_species_countries - Name of the field collection
  • field_species_country - Actual field inside the field collection

Limitations: I think this has some limitations because the second query contains ... WHERE field IN (1, 2, 3 ...). For MySQL this is limited by max_allowed_packet

2
  • I ll try this out and let you know.. Cheers mate. Apr 13, 2012 at 9:05
  • 1
    This was quite helpful, thanks! It took me a bit to wrap my head around, so might be worth emphasizing the key part is you have to run a second EntityFieldQuery, which returns the EntityIds of the relevant field collection items, which then get plugged into the main query's fieldCondition method.
    – aendra
    Dec 10, 2012 at 12:53
0

I think you'll want to use the delta_group parameter to let EFQ know that the fields are supposed to be related. There's a good explanation in this comment on the fieldCondition documentation.

The $delta_group parameter allows you to group conditions together. I have always read the docs to mean that we were specifying the delta within the field itself, but this is not the case.

For example, if you want to select entities based on two columns from the same field, you use a delta group to make sure that the conditions are dependent.

3
  • Hate to be a downvoter, but this isn't true as far as I can tell -- like Clive said, EntityFieldQuery has no concept that the two bundles are related; they essentially act as two separate entity types. That said, if you can do a proof-of-concept using delta_groups, I'll happily un-downvote.
    – aendra
    Dec 10, 2012 at 12:57
  • aendrew, am I misunderstanding what's going on in this code example, or misunderstanding the question? drupal.org/node/916776#comment-4011564
    – beth
    Dec 10, 2012 at 14:41
  • I think the question -- the delta group just ties conditions together (much like adding parentheses in an if-statement). What the question is asking for is essentially to query one entity type and then use the results of that as a condition in a second query. The field in question is a Field Collection, which is a separate entity type with its own unique fields (It's kind of hard to explain if you've never used Field Collections -- though, it's a pretty cool module and worth checking out if not).
    – aendra
    Dec 10, 2012 at 17:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.