1

I have a content type which contains fields which I am filtering my results on. Of these results, I wish to get the email address of the user who authored the node.

Currently I am using an Entity Field Query to get the list of nids. There can be thousands of matching nodes.

To get the email addresses of the authors of the nodes I do a node_load_multiple with the nids of my EFQ, and then a user_load_multiple with the uids of those nodes.

Is there a way to cut out a few of those steps with EFQ? Or will performance not be as big of an issue as I think it is?

Here is a code example:

$query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
        ->entityCondition('bundle', 'application')
        ->propertyCondition('status', 1)
        ->fieldCondition('field_one', 'value', $value1)
        ->fieldCondition('field_two', 'tid', $value2)
        ->fieldCondition('field_three', 'tid', NULL, 'IS NOT NULL');
  $result = $query->execute();

  if (isset($result['node'])) {
    $nodes = node_load_multiple(array_keys($result['node']));
    $uids = array();
    foreach ($nodes as $node) {
      $uids[$node->uid] = $node->uid;
    }
    $users = user_load_multiple(array_keys($uids));
  }
2

You are doing a lot of potentially unnecessary loads. Unless you need those nodes at some point on the page request, you will be doing a lot of unnecessary database reads.

I would EFQ to get the node list, and then do another query to just get the $uids. This example will retrieve the node list you're looking for:

$efq = new EntityFieldQuery();
$efq->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'application')
  ->propertyCondition('status', 1)
  ->fieldCondition('field_one', 'value', $value1)
  ->fieldCondition('field_two', 'tid', $value2)
  ->fieldCondition('field_three', 'tid', NULL, 'IS NOT NULL');
$result = $efq->execute();

if (isset($result['node'])) {
  $query = db_query('SELECT DISTINCT uid FROM {node} WHERE nid IN :nids', 
    array(':nids', array_keys($result['node'])));

  $uids = $query->execute->fetchCol();
  $users = user_load_multiple($uids);
}
  • Thanks, do you think an EFQ is not the best way of doing this? I've contemplated just using a single db_query or db_select as all I really need are the users' mail fields. I thought I'd try to avoid having to write a more complex multiple join query, but that might just be the smartest and most efficient way. – dieuwe Jan 10 '14 at 4:44
  • @dieuwe Unless the query is on a high volume page, I don't worry about things like this. A db_select() will be faster (the EFQ includes an automagic node_access, which you should always use for the node table), but I like the convenience of EFQ so I don't need to remember table/column names. – mpdonadio Jan 10 '14 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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