lucene(12)—lucene搜索之分组处理group查询
grouping介绍
我们在做lucene搜索的时候,可能会用到对某个条件的数据进行统计,比如统计有多少个省份,在sql查询中我们可以用distinct来完成类似的功能,也可以用group by来对查询的列进行分组查询。在lucene中我们实现类似的功能怎么做呢,比较费时的做法时我们查询出所有的结果,然后对结果里边的省份对应的field查询出来,往set里边放,显然这种做法效率低,不可取;lucene为了解决上述问题,提供了用于分组操作的模块group,group主要用户处理不同lucene中含有某个相同field值的不同document的分组统计。
Grouping可以接收如下参数:
- groupField:要分组的字段;比如我们对省份(province)进行分组,要传入对应的值为province,要注意的是如果groupField在document中不存在,会返回一个null的分组;
- groupSort:分组是怎么排序的,排序字段决定了分组内容展示的先后顺序;
- topNGroups:分组展示的数量,只计算0到topNGroup条记录;
- groupOffset:从第几个TopGroup开始算起,举例来说groupOffset为3的话,会展示从3到topNGroup对应的记录,此数值我们可以用于分页查询;
- withinGroupSort:每组内怎么排序;
- maxDocsPerGroup:每组处理多少个document;
- withinGroupOffset:每组显示的document初始位置;
group的实现需要两步:
- 第一步:利用TermFirstPassGroupingCollector来收集top groups;
- 第二步:用
TermSecondPassGroupingCollector处理每个group对应的documents
group模块定义了group和group的采集方式;所有的grouping colletor,所有的grouping collector都是抽象类并且提供了基于term的实现;
实现group的前提:
要group的field必须是必须是SortedDocValuesField类型的;
solr尽管也提供了grouping by的相关方法实现,但是对group的抽象实现还是由该模块实现;
暂不支持sharding,我们需要自己提供groups和每个group的documents的合并
group示例
|
|
利用BlockGroupingCollector
我们有时候想要在索引的时候就将group字段存入以方便search,我们可以在确保docs被索引的前提下,先查询出来每个要group的term对应的documents,然后在最后的document插入一个标记分组的field,我们可以如此做:
|
|
在分组查询的时候,我们可以
|
|
我们也可以直接进行group的查询,此为通用的实现
查询方法
|
|
以下是查询的工具类
查询工具类
|
|