https://solr.apache.org/guide/8_6/result-grouping.html
近似于facet, 相当于facet结果的每个桶里追加上几个桶内的文档.
分两阶段执行:
阶段1: 确定返回哪些桶, 以及桶的排序. 桶的排序只与sort参数有关, group.sort阶段1不会用到.
阶段2: 给每个桶补充文档.
Query: 原始查询q.
Collector: FirstPassGroupingCollector
数据节点在阶段1获取自己shard内的Top N个桶(也称为group).
可以看成是先把group.field的所有取值values枚举出来, 生成N个桶, 每个桶代表一个值value. 如果一个文档的group.field取值为value, 那么他就被装到值为value的桶里.
每个桶有一个sortValue, 这个sortValue就是桶内所有文档的最佳排序值. 比如说sort=score desc, 那么每个桶的排序值就是桶内所有文档得分取max. 比如说sort=field1 asc, 那么每个桶的排序值就是桶内所有文档的field1字段值取min.
然后所有的桶根据sort方式, 按照桶的排序值排序, 取 Top rows个, 就得到了最终要返回桶的列表.
Merge处理器: SearchGroupShardResponseProcessor.
每个shard返回自己的Top N个group时, 每个group会带上其最佳文档排序值(即sortValue).
协调节点对多个shard返回的桶列表做合并, 把每个数据节点返回的 Top N个桶最终合并为全局的Top N个桶.
合并的时候也是根据sort排序方式和每个桶的最佳文档排序值作为根据.
综合数据节点和协调节点的处理可以看出, 最终返回桶的列表只和group.field, rows, sort 3个参数有关.
Query: 原始查询q.
Collector: TopGroupsCollector(extends SecondPassGroupingCollector)
核心逻辑就是给每个桶创建一个collector, collector的numHits设置为group.limit, collector的排序方式是group.sort. 用查询q重新查一遍, 每个文档先获取其group.field值, 根据值可以确定当前文档属于哪个桶, 然后把这个文档加入该桶(在每个桶内是以group.sort方式给所有文档排序的, 最终每个桶取Top group.limit 个文档.).
Merge处理器: TopGroupsShardResponseProcessor.
这块源码没细看, 猜也能猜到:
应该以group为粒度合并多个shard返回的文档列表. 具体的合并逻辑就和正常搜索合并多个shard的文档列表一样的, 无非是每个group下的文档列表单独走一遍合并逻辑.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。