Tôi có một loại nút bài viết với trường tham chiếu các bài viết liên quan.
Nếu một bài báo có ít hơn 4 tài liệu tham khảo cho lĩnh vực đó, tôi cần tìm kiếm các bài viết khác mà
- không phải là nút hiện tại
- đã được cập nhật ít hơn 2 năm trước
- có hộp kiểm 'yêu thích' được chọn
- chia sẻ ít nhất một id văn hóa (tham chiếu phân loại) VÀ ít nhất một id chủ đề (tham chiếu phân loại)
Và tôi thực sự đang tự hỏi làm thế nào để thực hiện nhu cầu cuối cùng đó...
Dựa trên Thực hiện truy vấn với điều kiện trường thực thể có nhiều giá trị, tôi đã viết đoạn mã sau:
<?php
không gian tên Drupal\my_module\Pre process;
sử dụng Drupal\Core\DependencyInjection\ContainerInjectionInterface;
sử dụng Drupal\Core\Entity\EntityTypeManagerInterface;
sử dụng Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Loại nút tiền xử lý Article.
*/
lớp MyArticle triển khai ContainerInjectionInterface {
const MAX_RELATED_ARTICLES = 4;
/**
* Lưu trữ thuật ngữ phân loại.
*
* @var \Drupal\node\NodeStorage
*/
$nodeStorage được bảo vệ;
/**
* Trình tạo lớp.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Trình quản lý kiểu thực thể.
*/
hàm công khai __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->nodeStorage = $entity_type_manager->getStorage('node');
}
/**
* {@inheritdoc}
*/
tạo hàm tĩnh công khai (ContainerInterface $container) {
trả về tĩnh mới (
$container->get('entity_type.manager')
);
}
/**
* Bài báo loại nút tiền xử lý.
*
* @param mảng biến $
* Một mảng các biến được sử dụng để hiển thị nút.
*/
tiền xử lý hàm công khai(mảng &$biến) {
if ('full' === $variables['view_mode']) {
$this->preprocessFull($variables);
}
}
/**
* Bài báo loại nút tiền xử lý ở chế độ xem đầy đủ.
*
* @param mảng biến $
* Một mảng các biến được sử dụng để hiển thị nút.
*/
tiền xử lý hàm được bảo vệFull(mảng &$biến) {
$node = $variables['node'];
$relative_articles = $node->get('relative_articles')->referencedEntities();
$themes = $node->get('themes')->referencedEntities();
$cultures = $node->get('cultures')->referencedEntities();
$themes_ids = $cultures_ids = [];
foreach ($themes as $term) {
$themes_ids[] = $term->id();
}
foreach ($cultures as $term) {
$cultures_ids[] = $term->id();
}
$nb_liên quan_articles = đếm($liên quan_bài viết);
if ($nb_relative_articles < self::MAX_RELATED_ARTICLES) {
$limit = self::MAX_RELATED_ARTICLES - $nb_relative_articles;
$changed_boundary = strtotime('-2 năm');
$query = $this->nodeStorage->getQuery()
->điều kiện('loại', 'bài viết')
->điều kiện('trạng thái', 1)
->điều kiện('nid', $node->id(), '<>')
-> điều kiện ('yêu thích', 1)
->điều kiện('đã thay đổi', $changed_boundary, '>=')
->phạm vi(0, giới hạn $);
$or_themes = $or_cultures = $query->orConditionGroup();
foreach ($themes_ids as $tid) {
$or_themes->condition('cultures', $tid);
}
foreach ($cultures_ids as $tid) {
$or_cultures->condition('themes', $tid);
}
$and = $query->andConditionGroup()
->điều kiện($or_themes);
$truy vấn->điều kiện($và);
$and = $query->andConditionGroup()
->điều kiện($or_cultures);
$truy vấn->điều kiện($và);
$node_ids = $query->execute();
}
}
}
mang lại cho tôi truy vấn sau:
CHỌN "base_table".."vid" NHƯ "vid", "base_table".."nid" NHƯ "nid"
TỪ "nút" "base_table"
INNER THAM GIA "node_field_data" "node_field_data" BẬT "node_field_data".."nid" = "base_table".."nid"
INNER THAM GIA "node__favorite" "node__favorite" BẬT "node__favorite".."entity_id" = "base_table".."nid"
THAM GIA TRÁI "node__cultures" "node__cultures" TRÊN "node__cultures".."entity_id" = "base_table".."nid"
THAM GIA TRÁI "node__themes" "node__themes" BẬT "node__themes".."entity_id" = "base_table".."nid"
THAM GIA TRÁI "node__cultures" "node__cultures_2" BẬT "node__cultures_2".."entity_id" = "base_table".."nid"
THAM GIA TRÁI "node__themes" "node__themes_2" BẬT "node__themes_2".."entity_id" = "base_table".."nid"
WHERE ("node_field_data".."type" = 'bài viết')
VÀ ("node_field_data".."status" = 'NODE_PUBLISHED')
AND ("node_field_data".."nid" <> '19533')
VÀ ("node__favorite".."favorite_value" = '1')
VÀ ("node_field_data".."đã thay đổi">= '1583280325')
VÀ (("node__cultures".."cultures_target_id" = '5077') hoặc ("node__themes".."themes_target_id" = '42') hoặc ("node__themes".."themes_target_id" = '38'))
VÀ (("node__cultures_2".."cultures_target_id" = '5077') hoặc ("node__themes_2".."themes_target_id" = '42') hoặc ("node__themes_2".."themes_target_id" = '38'))
NHÓM THEO base_table.vid, base_table.nid
GIỚI HẠN 4 BÙA 0
Và đó không phải là điều tôi mong đợi vì tôi cần điều kiện AND giữa id văn hóa và id chủ đề.
Tôi sẽ cần một cái gì đó như:
AND (("node__cultures".."cultures_target_id" = '5077') AND (("node__themes".."themes_target_id" = '42') hoặc ("node__themes".."themes_target_id" = '38')))
thay vì
VÀ (("node__cultures".."cultures_target_id" = '5077') hoặc ("node__themes".."themes_target_id" = '42') hoặc ("node__themes".."themes_target_id" = '38'))
Vì vậy, câu hỏi của tôi là: có cách nào để đạt được điều này với And/OrConditionGroup hay tôi nên sử dụng các truy vấn phụ để khớp với một số id cụ thể cho cả chủ đề và nền văn hóa?