使用具有多个值的实体字段条件执行查询


14

我有一个具有实体引用字段的内容类型,该字段允许用户在该字段中添加多个分类法术语。我正在尝试执行查询,以获取在该字段内具有一组特定分类法术语的节点。

像这样,在该字段中使用一个值可以很好地工作。

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

其中2是我要搜索的术语的ID。但是,当我尝试搜索包含两个特定术语的节点时,

    $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 项8的每个节点,而不是预期的项2 项8。如何执行查询,以检查节点在实体引用字段中是否具有多个特定值?

Answers:


19

使用两个单独的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') )

他尝试了上面的等效代码,但未返回任何值,您是否检查此代码是否有效?
Eyal

是的,它适用于标准文章和带有多个标签的标签字段。
4k4

也许我的建议失败了,因为我这样写了$and->condition('custom_taxonomy', [2], 'IN')$and->condition('custom_taxonomy', [8], 'IN')
Eyal

3
没关系,只需对其进行测试即可'IN'。区别在于两个独立的AND组。
21:02

3
很好,不知道这行得通。很有道理,因为这会在内部强制多个联接。
贝尔迪尔'17

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
我实现了答案,但是由于某种原因,它没有显示正确的结果。如果我仅使用$ and条件之一,例如[2],'IN'或[8],'IN',则显示结果就很好,但是当我同时使用这两个条件时,不会得到任何结果。我进行了三重检查,以确保我同时拥有两个节点。
马特

1
考虑一下,由于实体查询默认使用AND,因此不需要AND conditionGroup。
Eyal

1
好的,我将其更改为仅使用$ query-> condition(),但是仍然存在一个问题,即同时使用它时,它不会显示任何结果。
马特

1
根据QueryInterface :: condition文档,您可以在增量上应用条件。我将用示例代码更新答案。
Eyal

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,
  ];
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.