Получить имя тега (термина) для нескольких узлов без снижения производительности
Я хочу получить список узлов и вернуть их в формате JSON вместе с их тегами (включая имена). После долгих исследований я пришел только к такому решению:
У меня есть массив узлов (\Drupal\Core\Entity\EntityInterface
), загруженный Node::loadMultiple()
.
Перебор массива узлов и получение их тегов с использованием $node->field_tags
(или независимо от имени машины тегов), что дает массив \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem
Получение всех терминов узла с помощью Term::loadMultiple()
, а затем повторение их и получение имени с помощью $term->name[0]->value
.
Проблема в том, что для каждого узла есть дополнительная база данных для чтения, и я предполагаю, что основным запросом для этого чтения является СОЕДИНЕНИЕ:|.
Вопрос: Существует ли эффективный способ загрузки имен тегов (терминов) вместе с target_id
, target_type
, target_uuid
, и т.д.? Если нет, то является ли текущий цикл на каждом узле правильным путем???
Дополнительная Информация:
- Я разбиваю результаты на страницы
- Клиент может установить количество результаты на страницу, но есть ограничение в 50 узлов на страницу
Спасибо
P.S.: У меня есть еще два типа тегов, поэтому мне нужно сделать это еще два раза. Яркая сторона в том, что два других тега - 1to1.
1 answers
Если вы уже перебираете массив узлов, рассматривали ли вы возможность сбора идентификаторов терминов перед их загрузкой в один запрос? Это должно сэкономить много накладных расходов при выполнении нескольких запросов:
$map = [];
$tids = [];
// Collect IDs for each node:
/** @var \Drupal\node\Entity\NodeInterface[] $nodes */
foreach ($nodes as $nid => $node) {
/** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item */
foreach ($node->field_tags as $item) {
$tid = $item->target_id;
$map[$nid][$tid] = $tid;
$tids[$tid] = $tid;
}
}
// Load terms and collect their labels:
$term_labels = [];
/** @var \Drupal\taxonomy\Entity\TermInterface $term */
foreach (Term::loadMultiple($tids) as $tid => $term) {
$term_labels[$tid] = $term->label();
}
// Assign the term labels to each node.
foreach ($map as $nid => $node_tids) {
foreach ($node_tids as $tid) {
$map[$nid][$tid] = $term_labels[$tid];
}
}