複数の値を持つエンティティフィールド条件でクエリを実行する


14

ユーザーがそのフィールドに複数の分類用語を追加できるエンティティ参照フィールドを持つコンテンツタイプがあります。そのフィールド内に特定の分類用語のセットを持つノードを取得するクエリを実行しようとしています。

そのフィールドで1つの値を使用すると、うまく機能します。

    $query = \Drupal::entityQuery('node')
        ->condition('status', NODE_PUBLISHED)
        ->condition('type', 'custom_type')
        ->condition('custom_taxonomy', 2)
        ->sort('field_last_name', DESC);

ここで、2は検索する用語のIDです。ただし、そのような2つの特定の用語を含むノードを検索しようとすると、

    $query = \Drupal::entityQuery('node')
        ->condition('status', NODE_PUBLISHED)
        ->condition('type', 'custom_type')
        ->condition('custom_taxonomy', [2,8])
        ->sort('field_last_name', DESC);

エラーが表示されます

無効なパラメーター番号:バインドされた変数の数がトークンの数と一致しません:

私も試みました

    $query = \Drupal::entityQuery('node')
        ->condition('status', NODE_PUBLISHED)
        ->condition('type', 'custom_type')
        ->condition('custom_taxonomy', [2,8], 'IN')
        ->sort('field_last_name', DESC);

これは失敗しませんが、意図した結果を提供しません。これは、どちらかの用語2持っているすべてのノードが表示さOR代わり項2の期間8 意図される用語8を。ノードのエンティティ参照フィールドに複数の特定の値があるかどうかを確認するクエリを実行するにはどうすればよいですか?

回答:


19

2つの個別のを使用しますandConditionGroup()

$query = \Drupal::entityQuery('node')
  ->condition('status', NODE_PUBLISHED)
  ->condition('type', 'custom_type');
$and = $query->andConditionGroup();
$and->condition('custom_taxonomy', 2);
$query->condition($and);
$and = $query->andConditionGroup();
$and->condition('custom_taxonomy', 8);
$query->condition($and);
$result = $query->execute();

これは、フィールドにいくつの用語があるか、どのデルタにあるかに関係なく機能します。

編集

これにより、次のSQLが生成されます。

SELECT base_table.vid AS vid, base_table.nid AS nid
FROM 
{node} base_table
INNER JOIN {node_field_data} node_field_data ON node_field_data.nid = base_table.nid
INNER JOIN {node__custom_taxonomy} node__custom_taxonomy ON node__custom_taxonomy.entity_id = base_table.nid
INNER JOIN {node__custom_taxonomy} node__custom_taxonomy_2 ON node__custom_taxonomy_2.entity_id = base_table.nid
WHERE  (node_field_data.status = '1') AND (node_field_data.type = 'custom_type') AND( (node__custom_taxonomy.custom_taxonomy_target_id = '2') )AND( (node__custom_taxonomy_2.custom_taxonomy_target_id = '8') )

彼は上記の同等のコードを試しましたが、値が返されませんでしたが、このコードが機能することを確認しましたか?
エアル

はい、複数のタグで満たされた標準の記事とタグのフィールドで機能します。
4k4

私はそれがとても好きで書いたので、たぶん私の提案は失敗し$and->condition('custom_taxonomy', [2], 'IN')$and->condition('custom_taxonomy', [8], 'IN')
エヤル

3
それは問題ではなく、テストしただけで動作し'IN'ます。違いを生むのは、2つの別個のANDグループです。
4k4

3
いいですね、これが機能することを知りませんでした。これは理にかなっています。これにより、複数の結合が内部的に強制されます。
ベルディール

8

複雑なクエリを要求どおりに実行するには、条件グループを使用して、デルタをクエリする必要があります。

$query = \Drupal::entityQuery('node');
$query->condition('status', NODE_PUBLISHED)
  ->condition('type', 'custom_type')
  ->condition('custom_taxonomy', [2, 8], 'IN')
  ->condition('custom_taxonomy.%delta', 2, '=')
  ->sort('field_last_name', DESC);
$or = $query->orConditionGroup();
$or->condition('custom_taxonomy.0.target_id', 2);
$or->condition('custom_taxonomy.0.target_id', 8);
$query->condition($or);

QueryInterface :: conditionのドキュメントを参照してください。


1
答えを実装しましたが、何らかの理由で適切な結果が表示されません。[2]、 'IN'または[8]、 'IN'のように$ and条件の1つのみを使用すると、結果は正常に表示されますが、両方を使用すると、結果が得られません。両方のノードがあることを確認するためにトリプルチェックを行いました。
マット

1
それについて考えると、entityQueryはデフォルトでANDを使用するため、AND conditionGroupの必要はありません。
エアル

1
さて、$ query-> condition()を使用するように変更しましたが、両方を使用すると結果が表示されないという問題がまだあります。
マット

1
QueryInterface :: conditionのドキュメントに従って、デルタに条件を適用できます。サンプルコードで回答を更新します。
エヤル

1
@ Eyal、AND条件グループは冗長なようですが、同じフィールドに複数の条件を指定すると本当に役立ちます。各条件を個別のANDグループに入れるだけです。
4k4

1
$taxonomy_term = 'taxonomy_term';
    $vid = 'name_taxon';
    $terms = $this->entity_type_manager->getStorage($taxonomy_term)
      ->loadTree($vid);

foreach ($terms as $term) {
  $term_data[] = [
    "vid" => $term->vid,
    "name" => $term->name,
  ];
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.