Виконайте запит із умовою поля сутності з кількома значеннями


14

У мене є тип вмісту, який містить посилання на сутність, що дозволяє користувачам додавати в це поле кілька термінів таксономії. Я намагаюся виконувати запити, які захоплюють вузли, які мають певний набір таксономічних термінів у цьому полі.

Використання одного значення в цьому полі працює добре, як так.

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

Де 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, або термін 8. Замість терміна 2 І терміна 8 за призначенням. Як я можу виконати запит, який перевіряє, чи має вузол кілька конкретних значень у посилальному полі сутності?

Відповіді:


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

Так, воно працює для стандартного поля статті та тегів, заповненого кількома тегами.
4к4

Можливо, моя пропозиція не вдалася, тому що я написав це так $and->condition('custom_taxonomy', [2], 'IN'),$and->condition('custom_taxonomy', [8], 'IN')
Eyal

3
Це не має значення, просто перевірений, працює і з ним 'IN'. Відмінність - це дві окремі групи І.
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 :: документацію про стан .


1
Я реалізував відповідь, але чомусь це не відображає належних результатів. Якщо я використовую лише одну з умов $ і, наприклад [2], 'IN' або [8], 'IN', результати відображаються просто чудово, але коли я використовую обидва, я не отримую жодних результатів. Я потрійно перевірив, чи є у мене вузли, які мають обидва.
Метт

1
Думаючи про це, немає потреби в групі AND умова, тому що сутністьQuery використовує AND за замовчуванням.
Еял

1
Гаразд, я змінив його лише за допомогою $ query-> condition (), але у мене все ще виникає проблема, яка при використанні обох не відображає жодних результатів.
Метт

1
Відповідно до документації QueryInterface :: умова, ви можете застосувати умови до дельти. Я оновлю відповідь на прикладі коду.
Еял

1
@Eyal, група умов 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,
  ];
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.