2

How to query all the values of a particular field. I used Drupal\Core\Database\Connection object to fetch the values as below:

$connection = \Drupal::database();
$result = $connection->select('node__body', 'n')
  ->fields('n', array('body_value'))
  ->execute()->fetchCol();

Is there any Drupal 8 API specifically for this? I need to fetch all values of the field and fetch the field values for a particular node bundle.

  • There is no API for this.The only official API is loading the entities. – Berdir Jun 19 '15 at 9:07
  • So what I am doing is right? – Pravin Ajaaz Jun 19 '15 at 9:12
  • 2
    No, it's not "right". You shouldn't be doing it, there is no guarantee that it will continue to work or will return correct results. If you do anything like that, you're on your own. – Berdir Jun 19 '15 at 9:15
  • So in order fetch all field values, should I load entities in which it is present? – Pravin Ajaaz Jun 19 '15 at 9:21
7

In Drupal 7, you would use the EntityFieldQuery class. In Drupal 8, there is an equivalent service.

$query = \Drupal::entityQuery('node')
    ->condition('status', 1)
    ->condition('changed', REQUEST_TIME, '<')
    ->condition('title', 'cat', 'CONTAINS')
    ->condition('field_tags.entity.name', 'cats');

$nids = $query->execute();

In your case, instead of field_tag.entity.name, you need body.body_value. See EntityFieldQuery has been rewritten.
If you just need to get all the node IDs, remove all the condition() lines, and then use entity_load_multiple('node', $nids) to load the full node objects.

In this way, your code is not making assumptions about the tables used to contain the node data. Plus, it can be easily extended to filter the nodes basing on some criteria (node properties, content of fields...).

  • I think this will return nids of the nodes satisfying the condition but my need is to fetch all the field values in a particular content type. – Pravin Ajaaz Jun 19 '15 at 8:26
  • Once you have the node IDs, you can load the full node objects. – kiamlaluno Apr 19 '16 at 16:35
  • Instead of removing all conditions (which will load all nodes - which could be a lot), you presumably would want to use ->exists('field_name'). @see drupalsun.com/zhilevan/2017/01/14/query-drupal-8-entityquery – ognockocaten Jun 25 '18 at 21:09
2

Although entityQuery is very powerful I believe not everything can and should be done with it. Loading all nodes to get the values might consume to much resources. Using the Database API should be fine with some help of the TableMappingInterface, as stated in the documentation:

Provides a common interface for mapping field columns to SQL tables.

Warning: using methods provided here should be done only when writing code that is explicitly targeting a SQL-based entity storage. Typically this API is used by SQL storage classes, or other SQL-specific code like the Views integration code for the Entity SQL storage. Another example of legal usage of this API is when needing to write a query that \Drupal::entityQuery() does not support.

/** @var \Drupal\Core\Entity\Sql\TableMappingInterface $table_mapping*/
$table_mapping = \Drupal::entityTypeManager()->getStorage('node')->getTableMapping();

$field_table = $table_mapping->getFieldTableName('field_categories');
$field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('node')['field_categories'];
$field_column = $table_mapping->getFieldColumnName($field_storage_definitions, 'target_id');

$connection = \Drupal::database();
$result = $connection->select($field_table, 'f')
  ->fields('f', array($field_column))
  ->distinct(TRUE)
  ->condition('bundle', 'article')
  ->condition('entity_id', $nids, 'IN')
  ->execute()->fetchCol();

This works so far. But there are still asumptions about the columns bundle and entity_id. I am not sure if it would be save to assume that they will be allways there. Maybe there are also functions to get the bundle and the entity-id column, but I guess not, because it seems that views makes the same asumptions, see views_field_default_views_data.

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.