场景描述:
普通查询时,查询的结果中,个人信息有很多重复的,按照业务需求需要将重复的个人信息隐藏,所以使用分组查询,如果想查看隐藏的部分,则在具体分组中继续使用分页的查询。
分组查询:
JAVA部分代码:
- ...
- // 创建solrQuery对象
- SolrQuery query = new SolrQuery();
- query.set("q", "*:*" );
- /*分组*/
- //是否分组
- query.setParam("group", true);
- //分组的字段,不可以是多值字段
- query.setParam("group.field", "PAT_ID");
- //分组中每个组的上限数量,默认为1
- query.setParam("group.limit","2");
- //分布式模式使用分组,并返回分组数量
- query.setParam("group.ngroups","true");
- // 设置start,开始的组
- query.setStart(0);
- // 设置rows,返回多少组
- query.setRows(10);
- // 执行搜索,返回response对象
- QueryResponse rq = cloudSolrClient.query(query);
- // 从response中获取想要的结果,因为结构与正常搜索的结构不一致,所以取数据时与普通搜索获取数据不一样
- GroupResponse groupResponse = rq.getGroupResponse();
- List<GroupCommand> groupCommandList &#61; groupResponse.getValues();
- SolrDocumentList solrDocumentList &#61; new SolrDocumentList();
- long count &#61; 0;
- long groupNum&#61;0;
- // 判断是否为空
- if(groupCommandList!&#61;null && groupCommandList.size()>0){
- // 匹配出的结果总数
- count &#61; groupCommandList.get(0).getMatches();
- // 分组总数
- groupNum &#61; groupCommandList.get(0).getNGroups();
- List<Group> groupList&#61;groupCommandList.get(0).getValues();
- // 遍历返回的每个分组
- for(Group group:groupList){
- // 若为普通搜索的结果则只有一条&#xff1b;若为分组详情则只有一组&#xff0c;将一组全部放入
- for(SolrDocument solrDocument:group.getResult()){
- // 将分组中的数放入最后一个参数
- solrDocument.addField("numFound",group.getResult().getNumFound());
- // 每个分组只取第一个
- solrDocumentList.add(solrDocument);
- }
- }
- }
- ...
查询结果在solrDocumentList中&#xff0c;处理成什么格式可以自己设置&#xff1b;groupNum为分组的组数&#xff0c;count为所有匹配的文档数&#xff08;不分组的匹配数&#xff09;&#xff1b;
Solr管理页面查询的结构如下&#xff1a;
分组中的分页&#xff1a;
JAVA部分代码&#xff1a;
- //分组中的偏移量&#xff0c;相当于普通搜索中的start
- query.setParam("group.offset",String.valueOf(map.get("groupOffset")));
- //分组中每个组的上限数量&#xff0c;相当于普通搜索中的每页数量rows&#xff0c;默认为1
- query.setParam("group.limit",String.valueOf(map.get("groupLimit")));
《Solr实战》中这样写道&#xff1a;
- 结果分组功能在分布式模式下不能完全起作用。
- 如果计划在分布式模式下使用Solr的分组功能&#xff0c;并需要得到精确的分组数量&#xff08;由group.ngroups&#61;true参数返回&#xff09;。
- 如果没有按照计划那样&#xff0c;将数据按照分组的字段分割到各个分片上&#xff0c;那返回的分组数量仅仅是一个上限值。解决办法是
- 自定义散列&#xff0c;就是设置一个id让指定的一组文档分发到同一个分片上&#xff0c;这样做最大的问题是会造成集群里分片的不均衡。
经过多次测试&#xff0c;发现并没有发生文章中说的那样的问题。而且在尝试设置自定义散列的时候不知道该如何设置&#xff0c;起初我在配置文件中设置&#xff0c;但是没有效果。网上也没人设置过&#xff0c;没有出现上述问题&#xff0c;也就不再关心这个自定义散列了。
对于分组的参数&#xff0c;官网也有提及&#xff0c;如下&#xff1a;
对于分组的参数&#xff0c;官网也有提及&#xff0c;如下&#xff1a;
地址&#xff1a;https://wiki.apache.org/solr/FieldCollapsing
下面是别人翻译过来的&#xff1a;
地址&#xff1a;https://blog.csdn.net/jiangchao858/article/details/63256048
参数 | 类型 | 说明 |
---|---|---|
group | 布尔值 | 设为true&#xff0c;表示结果需要分组 |
group.field | 字符串 | 需要分组的字段&#xff0c;字段类型需要时是StrField或TextField |
group.func | 查询语句 | 可以指定查询函数 |
group.query | 查询语句 | 可以指定查询语句 |
rows | 整数 | 返回多少组结果&#xff0c;默认10 |
start | 整数 | 指定结果开始位置/偏移量 |
group.limit | 整数 | 每组返回多数条结果,默认1 |
group.offset | 整数 | 指定每组结果开始位置/偏移量 |
sort | 排序算法 | 控制各个组的返回顺序 |
group.sort | 排序算法 | 控制每一分组内部的顺序 |
group.format | grouped/simple | 设置为simple可以使得结果以单一列表形式返回 |
group.main | 布尔值 | 设为true时&#xff0c;结果将主要由第一个字段的分组命令决定 |
group.ngroups | 布尔值 | 设为true时&#xff0c;Solr将返回分组数量&#xff0c;默认fasle |
group.truncate | 布尔值 | 设为true时&#xff0c;facet数量将基于group分组中匹相关性高的文档&#xff0c;默认fasle |
group.cache.percent | 整数0-100 | 设为大于0时&#xff0c;表示缓存结果&#xff0c;默认为0。该项对于布尔查询&#xff0c;通配符查询&#xff0c;模糊查询有改善&#xff0c;却会减慢普通词查询。 |