web-dev-qa-db-ja.com

エンティティのフィールドの値を取得するにはどうすればよいですか?

特定のフィールドのすべての値をクエリする方法。 Drupal\Core\Database\Connection object以下のように値をフェッチします。

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

Drupalこのための8つのAPIは特にありますか?フィールドのすべての値をフェッチし、特定のノードバンドルのフィールド値をフェッチする必要があります。

2
Pravin Ajaaz

Drupal 7では、 EntityFieldQuery クラスを使用します。Drupal 8では、同等のサービスがあります。

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

$nids = $query->execute();
_

あなたの場合、field_tag.entity.nameの代わりに、body.body_valueが必要です。 EntityFieldQueryが書き直されました を参照してください。
すべてのノードIDを取得するだけの場合は、condition()行をすべて削除し、entity_load_multiple('node', $nids)を使用して完全なノードオブジェクトをロードします。

このように、コードはノードデータを含むために使用されるテーブルについての仮定を行いません。さらに、いくつかの基準(ノードのプロパティ、フィールドの内容...)に基づいてノードをフィルタリングするように簡単に拡張できます。

7
kiamlaluno

entityQuery は非常に強力ですが、すべてを使用して実行できるわけではなく、実行できるとは限りません。すべてのノードをロードして値を取得すると、多くのリソースが消費される可能性があります。ドキュメントに記載されているように、 データベースAPI の使用は TableMappingInterface の助けを借りてうまくいくはずです:

フィールド列をSQLテーブルにマッピングするための共通インターフェースを提供します。

警告:ここで提供されるメソッドは、SQLベースのエンティティストレージを明示的に対象とするコードを記述する場合にのみ使用してください。通常、このAPIは、SQLストレージクラス、またはエンティティSQLストレージのビュー統合コードなどの他のSQL固有のコードによって使用されます。このAPIの正当な使用法の別の例は、\ Drupal :: entityQuery()がサポートしないクエリを記述する必要がある場合です。

/** @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();

これはこれまでのところ機能します。ただし、列bundleおよびentity_idについては、まだ前提があります。彼らがずっとそこにいると仮定するのが救われるかどうかはわかりません。バンドルとエンティティID列を取得する関数もあるかもしれませんが、ビューは同じ仮定をしているように見えるので、私はそうは思いません。参照 views_field_default_views_data

2
LarS