Рейтинг:2

Использование API запросов сущностей для идентификации сущностей с коррелированными значениями

флаг ai

Представьте себе два настраиваемых типа сущностей Drupal 9 с именами а и б.

Тип объекта а имеет два поля а_f1 и а_f2.

Тип объекта б есть поле б_а которая является ссылкой на объект с целевым типом а и неограниченное количество элементов.

Как создать запрос объекта, который находит все объекты типа б хотя бы один из которых б_а ссылки на объекты указывают на а объект, который имеет значение «v1» для своего поля а_f1 и значение 'v2' для его поля а_f2?

В данном случае нецелесообразно искать б который имеет одну ссылку на сущность, указывающую на а сущность с а_f1 версии 1, но а_f2 «что-то еще», и ссылка на другой объект, указывающая на другой а сущность с а_f2 из 'v2', но а_f1 «неправильного значения».

Я мог бы сделать это во сне с помощью прямых SQL-запросов, но в мире Drupal это не одобряется. Мне трудно найти руководство для этого Друпал Путь в официальной документации Drupal.

Поддерживает ли API запросов объектов Drupal эту функцию?

Рейтинг:3
флаг us

Следующий код позволит достичь того, что описано в вопросе.

$результат = \Drupal::entityQuery('b')
  ->условие('b_a.entity:a.a_f1', 'v1')
  ->условие('b_a.entity:a.a_f2', 'v2')
  ->выполнить();

В первой строке, переданной условие():

  • б_а это имя поля
  • .сущность:а говорит, что поле является ссылкой на объект для а юридическое лицо
  • а_f1 и а_f2 поля для а юридическое лицо

Для получения дополнительной информации о значениях, принятых для первого условие() аргумент см. QueryInterface::условие().

В случае б_а field является полем с несколькими значениями, оба условия будут ссылаться на одну и ту же дельту, что означает значение а_f1 и A_f2 поля берутся из того же а юридическое лицо.
Код, который я написал в начале ответа, возвращает все объекты, для которых выполняются оба условия. Если вы хотите получить все объекты, для которых одно из условий истинно, следует использовать следующий код.

$query = \Drupal::entityQuery('b');
$group = $query->orConditionGroup()
  ->условие('b_a.entity:a.a_f1', 'v1')
  ->условие('b_a.entity:a.a_f2', 'v2');
$результат = $запрос->условие($группа)->выполнить();
флаг ai
Потрясающий! Большое спасибо. По-видимому, у меня нет разрешения на этом сайте голосовать за ваш ответ, иначе я бы это сделал, но я отметил его как правильный ответ (после создания и тестирования случая воспроизведения). Это делает именно то, что мне нужно было сделать. Есть ли где-нибудь документация, в которой объясняется, что API гарантирует, что оба значения должны исходить из одного и того же ссылочного объекта? И объясняет ли это, как построить запрос для случая, когда мне нужно найти объекты `b`, которые ссылаются на `a`, который имеет `a_f1 = 'v1'` **и** имеет `a`, где `a_f2 = 'v2'`, но они не обязательно должны быть одними и теми же объектами 'a'?
apaderno avatar
флаг us
Расширю ответ завтра (у меня уже почти полночь), но могу сказать, что для кода, который я показал, оба условия должны выполняться для каждой возвращаемой сущности. В настоящее время ответ не рассматривает поле с несколькими значениями.
флаг ai
Я подтвердил (экспериментально), что этот подход работает одинаково для многозначных полей с несколькими вхождениями (все указанные значения должны встречаться в одном и том же вхождении поля, чтобы родительский объект был включен в результаты запроса). Если вы знаете, где скрывается документация, объясняющая все это, пожалуйста, дайте ссылку. Я обещаю, что буду соответствующим образом смущен, если он будет лежать у всех на виду, а я его пропустил. :-)
apaderno avatar
флаг us
Я расширил ответ. В документации говорится, что два условия для одного и того же многозначного поля относятся к одной и той же дельте. это означает, что первое условие для `b_a.entity:a` не может относиться к первому элементу, а второе условие для `b_a.entity:a` – к третьему элементу.
флаг ai
Я собираюсь проигнорировать инструкции здесь, которые говорят мне, чтобы я не публиковал комментарии «спасибо». :-) Я очень ценю предоставленную вами информацию, а также ссылку на документацию (которую я должен был найти сам). И теперь похоже, что я (путем публикации комментариев) набрал достаточно очков «репутации», чтобы проголосовать за ваш ответ, что я и сделал. Спасибо!
apaderno avatar
флаг us
Иногда более очевидная страница документации — это не то место, где вы найдете информацию, которую ищете. Вот почему мы иногда не смотрим на это. Это случилось и со мной.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.