Drupal 9中如何在EntityQuery上添加表达式实现多日期字段排序
Drupal 核心的EntityQuery是兼容多种存储后端的抽象层,本身没有提供SQL专属的addExpression方法,所以无法直接调用该方法添加表达式,你可以通过以下两种方案实现多日期字段合并排序需求:
方案1:通过查询标签+钩子修改底层SQL查询
该方案可以保留EntityQuery的所有原有逻辑(包括访问控制、筛选条件、分页、标签等),仅追加排序逻辑,适合查询逻辑复杂的场景。
首先在构造EntityQuery时添加自定义查询标签:
// 构建基础节点查询 $query = \Drupal::entityTypeManager()->getStorage('node')->getQuery() ->accessCheck(TRUE) ->condition('type', ['article', 'page'], 'IN') ->condition('status', 1) // 追加自定义标签,用于后续修改查询逻辑 ->addTag('custom_article_page_date_sort'); // 原有其他查询逻辑、分页逻辑保持不变 $nids = $query->execute();
然后在自定义模块的.module文件中实现对应标签的查询alter钩子:
/** * Implements hook_query_TAG_alter() for custom_article_page_date_sort tag. */ function your_module_name_query_custom_article_page_date_sort_alter(Drupal\Core\Database\Query\SelectInterface $query) { // 关联两个日期字段的存储表,排除已软删除的字段数据 $query->leftJoin('node__field_date_1', 'fd1', 'fd1.entity_id = n.nid AND fd1.deleted = 0'); $query->leftJoin('node__field_date_2', 'fd2', 'fd2.entity_id = n.nid AND fd2.deleted = 0'); // 添加合并日期的表达式 $query->addExpression('COALESCE(fd1.field_date_1_value, fd2.field_date_2_value)', 'custom_sort_date'); // 设置排序规则 $query->orderBy('custom_sort_date', 'DESC'); }
方案2:原生SQL查询ID后批量加载实体
该方案逻辑更直观,不需要额外编写钩子,适合查询逻辑相对简单的场景。
// 直接构造SQL查询获取符合条件的节点ID $nids = \Drupal::database()->select('node', 'n') ->fields('n', ['nid']) ->condition('n.type', ['article', 'page'], 'IN') ->condition('n.status', 1) ->leftJoin('node__field_date_1', 'fd1', 'fd1.entity_id = n.nid AND fd1.deleted = 0') ->leftJoin('node__field_date_2', 'fd2', 'fd2.entity_id = n.nid AND fd2.deleted = 0') ->addExpression('COALESCE(fd1.field_date_1_value, fd2.field_date_2_value)', 'sort_date') ->orderBy('sort_date', 'DESC') // 按需添加分页 ->range(0, 20) ->execute() ->fetchCol(); // 批量加载节点实体,保持EntityQuery查询返回结果的格式一致 $nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
注意:如果你的站点开启了内容版本控制,或者日期字段设置为多值,需要根据实际的字段存储表结构调整关联的表名和关联条件。
内容的提问来源于stack exchange,提问作者Akansha
相关产品推荐
相关产品推荐

