4. 边界参数概念:搜索请求中的边界参数定义、分页、排序、过滤、高亮参数的作用域
在领域驱动设计的搜索索引聚合查询中,边界参数(Boundary Parameters)是连接用户查询意图与搜索引擎底层执行计划的关键契约。它们定义了“查什么、怎么查、返回什么、如何展示”的完整边界。本章将系统阐述分页、排序、过滤、高亮四大核心边界参数的定义、作用域及领域建模中的配置策略。
核心观点:边界参数不是简单的 HTTP 查询字符串,而是领域层对搜索交互协议的显式建模。每个参数都应具备明确的领域语义、作用域边界和默认值契约。
4.1 边界参数的定义与分类
边界参数从领域视角可分为三类:
| 分类 | 参数示例 | 作用域 | 领域语义 |
|---|---|---|---|
| 结果控制参数 | page, size, sort |
查询结果集 | 定义返回数据的数量、顺序和分段方式 |
| 条件约束参数 | filter, range, term |
查询条件域 | 缩小匹配范围,排除无关文档 |
| 展示增强参数 | highlight, fields, source |
响应展示层 | 控制返回字段、高亮片段等展示行为 |
领域建模提示:在聚合查询的边界参数配置中,建议将参数定义在独立的
SearchRequest 值对象中,而非散落在方法签名里。这有助于保持领域层的封装性和可测试性。
4.2 分页参数:深度与偏移的领域权衡
分页参数是最常见的边界参数,但其作用域往往被低估。典型的分页参数包括:
page:当前页码(从 0 或 1 开始)size:每页文档数from:偏移量(常用于深度分页)search_after:游标分页(避免深度分页性能问题)
不同分页策略的作用域对比:
| 策略 | 适用场景 | 作用域限制 | 领域风险 |
|---|---|---|---|
| 偏移分页(from + size) | 前几页查询,用户交互友好 | 深度分页时性能急剧下降 | 超过 10000 条后可能被搜索引擎拒绝 |
| 游标分页(search_after) | 深度分页、实时数据流 | 只能向前翻页,不支持随机跳转 | 需要维护排序字段的唯一性 |
| 键集分页(keyset) | 静态数据集、导出场景 | 依赖排序字段的稳定性 | 排序字段变更会导致数据遗漏 |
4.3 排序参数:领域有序性的显式表达
排序参数定义了搜索结果的有序规则。在领域驱动设计中,排序不应仅仅是字段名+方向的组合,而应体现领域的有序性语义。
排序参数的核心要素:
- 排序字段:必须是索引中已映射的字段,且通常为
keyword、numeric、date类型 - 排序方向:
asc(升序)或desc(降序) - 排序模式:
min、max、avg(适用于多值字段) - 缺失值处理:
_last、_first或自定义默认值
常见陷阱:在聚合查询中,排序参数的作用域可能被错误地应用到聚合桶内而非文档级别。务必在领域层明确区分“文档排序”与“聚合桶排序”的边界。
排序参数在领域模型中的配置示例:
// 领域层排序值对象
public class SortCriteria {
private String field; // 排序字段(领域字段名)
private SortDirection direction; // ASC / DESC
private SortMode mode; // MIN / MAX / AVG
private MissingValue missing; // _LAST / _FIRST / custom
// 领域工厂方法
public static SortCriteria byRelevance() {
return new SortCriteria("_score", SortDirection.DESC);
}
public static SortCriteria byDateDesc(String field) {
return new SortCriteria(field, SortDirection.DESC);
}
}
4.4 过滤参数:查询与过滤的领域边界
过滤参数(Filter)与查询参数(Query)在搜索引擎中有本质区别。过滤参数的作用域是精确匹配,不参与相关性评分,且结果可被缓存。
| 维度 | 查询参数(Query) | 过滤参数(Filter) |
|---|---|---|
| 作用域 | 影响相关性评分 | 仅做布尔匹配 |
| 缓存 | 不缓存 | 可缓存结果集 |
| 性能 | 相对较慢 | 更快,适合频繁执行 |
| 领域语义 | 用户意图匹配 | 业务规则约束 |
| 典型场景 | 全文搜索、模糊匹配 | 状态过滤、范围限定 |
过滤参数在聚合查询中的典型作用域:
- 全局过滤:应用于整个搜索请求,影响所有聚合桶
- 聚合级过滤:仅影响特定聚合桶的计算
- 后过滤:在查询和聚合计算完成后,对结果集做二次过滤
4.5 高亮参数:展示层的领域边界
高亮参数控制搜索结果中匹配片段的展示方式。虽然高亮是展示层行为,但其配置参数需要在领域层进行建模,以确保不同搜索场景的一致性。
高亮参数的核心配置项:
| 参数 | 作用域 | 说明 |
|---|---|---|
pre_tags / post_tags |
片段包裹 | 高亮前后缀标签,如 <em> |
fragment_size |
片段长度 | 每个高亮片段的字符数 |
number_of_fragments |
片段数量 | 每个字段返回的最大片段数 |
fields |
字段作用域 | 指定哪些字段需要高亮 |
type |
高亮算法 | unified、plain、fvh |
领域建模实践:将高亮参数封装为
HighlightConfig 值对象,并在领域层提供不同场景的工厂方法(如 forTitle()、forContent()),避免展示层直接拼接高亮参数。
4.6 边界参数的作用域层级模型
所有边界参数在搜索请求中形成层级作用域模型。理解这个模型是正确配置聚合查询的前提。
作用域层级的关键规则:
- 上层参数可被下层覆盖:全局分页参数可被聚合级的分页参数覆盖
- 过滤参数具有传递性:全局过滤条件自动传递到所有聚合桶
- 高亮参数作用域最小:仅影响最终返回的文档片段,不参与聚合计算
- 排序参数不可传递:文档排序与聚合桶排序是独立的边界
领域驱动设计原则:边界参数的作用域模型应在领域层通过值对象和工厂方法显式定义,而非在基础设施层通过 Map 或 JSON 对象隐式传递。这确保了参数变更时,领域逻辑的完整性不受破坏。