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


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.