1

I'm looking at building a simple key => value array with a certain type of node I have in order to generate a select list in a form.

The thing is that I have thousands of nodes of this type and the page takes forever to load with the current code I have.

Is there a way to load only certain fields using the QueryInterface in order to cut on loading times? Is there a more efficient way to do this?

$query = \Drupal::entityQuery('node')
  ->condition('type', 'product')
  ->condition('status', 1)
;

$nids = $query->execute();

$nodeStorage = \Drupal::entityTypeManager()->getStorage('node');

// Load multiple nodes
$nodes = $nodeStorage->loadMultiple($nids);

$list = array();

foreach ($nodes as $node) {
  $list[$node->field_code->value] = $node->title->value . ' (' . $node->field_code->value . ')';
}
  • entity query will give you only nids or whole nodes. So in order to get nid and title you have to use basic query. But if you have a lot of nodes I would suggest entity reference field instead. – user21641 Feb 25 '16 at 17:46
  • 1
    Even if you optimize the query, adding thousands of options to a select is really a bad idea. Entity autocomplete fields are really easy to use in d8. See api.drupal.org/api/drupal/… for example. just specifiy #target_type and use bundle selection settings to limit it to your node type. And as a result, you get the selected node. it does also validates. – Berdir Feb 25 '16 at 20:17
0

The only way I know to do this is similar to what @Ivan Jaros mentions in the comment above. That is to use a Database service instead of EntityQuery service. There is a handy method on the query Statement, fetchAllKeyed, that I use all of the time in Drupal 7.

$database = \Drupal::service('database');
$query = $database->select('node', 'n');
$query->join('node_field_data', 'nfd', 'n.nid = n.nfd.nid');
$query
  ->fields('n', ['nid']),
  ->fields('nfd', ['title']) 
  ->condition('n.type', 'product')
  ->condition('nfd.status', 1)
  ->execute()
  ->fetchAllKeyed();

Unfortunately this has drawbacks:

  1. Multilingual - you need to do this manually in the query above.
  2. Probably not going to work well with non-SQL drivers.
  3. Might run into performance issues still because the data is not cached.
| improve this answer | |

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.