Solr---Group分组查询

13 篇文章 0 订阅

场景描述:

        普通查询时,查询的结果中,个人信息有很多重复的,按照业务需求需要将重复的个人信息隐藏,所以使用分组查询,如果想查看隐藏的部分,则在具体分组中继续使用分页的查询。

分组查询:

JAVA部分代码:

	...
        // 创建solrQuery对象
	SolrQuery query = new SolrQuery();
	query.set("q", "*:*" );
	/*分组*/
	//是否分组
        query.setParam("group", true);
        //分组的字段,不可以是多值字段
        query.setParam("group.field", "PAT_ID");
        //分组中每个组的上限数量,默认为1
        query.setParam("group.limit","1");
        //分布式模式使用分组,并返回分组数量
        query.setParam("group.ngroups","true");
        //分组详情搜索
        //分组中的偏移量,相当于普通搜索中的start
        query.setParam("group.offset",jsonObject.getString("start"));
        //分组中每个组的上限数量,相当于普通搜索中的每页数量rows,默认为1
        query.setParam("group.limit",jsonObject.getString("rows"));
	// 执行搜索,返回response对象
	QueryResponse rq = cloudSolrClient.query(query);
	// 从response中获取想要的结果,因为结构与正常搜索的结构不一致,所以取数据时与普通搜索获取数据不一样
        GroupResponse groupResponse = rq.getGroupResponse();
        List<GroupCommand> groupCommandList = groupResponse.getValues();
        SolrDocumentList solrDocumentList = new SolrDocumentList();
        long count = 0;
        long groupNum=0;
        // 判断是否为空
        if(groupCommandList!=null && groupCommandList.size()>0){
            // 匹配出的结果总数
            count = groupCommandList.get(0).getMatches();
            // 分组总数
            groupNum = groupCommandList.get(0).getNGroups();
            List<Group> groupList=groupCommandList.get(0).getValues();
            // 遍历返回的每个分组
            for(Group group:groupList){
                // 若为普通搜索的结果则只有一条;若为分组详情则只有一组,将一组全部放入
                for(SolrDocument solrDocument:group.getResult()){
                    // 将分组中的数放入最后一个参数
                    solrDocument.addField("numFound",group.getResult().getNumFound());
                    // 每个分组只取第一个
                    solrDocumentList.add(solrDocument);
                }
            }
        }
        ...

        查询结果在solrDocumentList中,处理成什么格式可以自己设置;groupNum为分组的组数,count为所有匹配的文档数(不分组的匹配数);

Solr管理页面查询的结构如下:

分组中的分页:

JAVA部分代码:

            //分组中的偏移量,相当于普通搜索中的start
            query.setParam("group.offset",String.valueOf(map.get("groupOffset")));
            //分组中每个组的上限数量,相当于普通搜索中的每页数量rows,默认为1
            query.setParam("group.limit",String.valueOf(map.get("groupLimit")));
        配合这两个条件,进行分组中的分页。
《Solr实战》中这样写道:
    结果分组功能在分布式模式下不能完全起作用。
    如果计划在分布式模式下使用Solr的分组功能,并需要得到精确的分组数量(由group.ngroups=true参数返回)。
如果没有按照计划那样,将数据按照分组的字段分割到各个分片上,那返回的分组数量仅仅是一个上限值。解决办法是
自定义散列,就是设置一个id让指定的一组文档分发到同一个分片上,这样做最大的问题是会造成集群里分片的不均衡。
        经过多次测试,发现并没有发生文章中说的那样的问题。而且在尝试设置自定义散列的时候不知道该如何设置,起初我在配置文件中设置,但是没有效果。网上也没人设置过,没有出现上述问题,也就不再关心这个自定义散列了。

对于分组的参数,官网也有提及,如下:
下面是别人翻译过来的:

地址:https://blog.csdn.net/jiangchao858/article/details/63256048

参数类型说明
group布尔值设为true,表示结果需要分组
group.field字符串需要分组的字段,字段类型需要时是StrField或TextField
group.func查询语句可以指定查询函数
group.query查询语句可以指定查询语句
rows整数返回多少组结果,默认10
start整数指定结果开始位置/偏移量
group.limit整数每组返回多数条结果,默认1
group.offset整数指定每组结果开始位置/偏移量
sort排序算法控制各个组的返回顺序
group.sort排序算法控制每一分组内部的顺序
group.formatgrouped/simple设置为simple可以使得结果以单一列表形式返回
group.main布尔值设为true时,结果将主要由第一个字段的分组命令决定
group.ngroups布尔值设为true时,Solr将返回分组数量,默认fasle
group.truncate布尔值设为true时,facet数量将基于group分组中匹相关性高的文档,默认fasle
group.cache.percent整数0-100设为大于0时,表示缓存结果,默认为0。该项对于布尔查询,通配符查询,模糊查询有改善,却会减慢普通词查询。

 关于分组文档数量不一致问题的补充:

       《Solr实战》PDF文档下载地址)11.6章节有讲到关于“分组陷阱”的问题。

       上述“分组中的分页”以及自己计算总数,已解决本人在分组分页的问题,还可以采用《Solr实战》13.7章节中关于自定义散列的方式,即创建索引时将“分组字段!”作为前缀。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值