Solr 7.7.2如何在Collapse结果折叠前对指定分面做预聚合
Solr 7.7.2 CollapseParser 单分面折叠前计算实现方案
先说明你之前尝试的方案为啥没用
tag+ex的排除规则只对普通fq过滤器生效,CollapseQueryParser是结果集后置处理组件,根本不在普通过滤器的拦截链路里,用标签排除绕不开折叠逻辑,没效果是正常的。collapse.facet=facet.before在Solr 7.x线是全局开关,开了之后所有分面全走折叠前的全集计算,根本不支持给单个分面单独配置,而且7.7.2版本这个参数本身有bug,开了之后分页偏移、结果总条数统计都会出问题。
Solr 7.7.2原生的Collapse组件本身就没做单分面粒度的折叠前后混合计算支持,要实现需求直接用下面两个方案就行:
可行实现方案
方案1:应用层拆双请求合并(生产环境优先选,零改造成本无兼容问题)
把原请求拆成两个轻量请求,最后在业务层拼结果就行,性能损失可以忽略:
- 第一个请求专门算要提前聚合的那个分面:设
rows=0不返回任何文档,开collapse.facet=facet.before,请求里只带这一个分面字段的配置,其他分面、高亮、排序这些参数全删掉,这个请求只做单字段分面聚合,开销非常小。 - 第二个请求走正常折叠逻辑:按原有配置传参,正常返回分页文档、其余所有折叠后计算的分面、高亮结果,不要开before参数。
- 最后把第一个请求拿到的目标分面结果,替换掉第二个请求里对应字段的分面值,和文档列表一起返回前端就完事。
方案2:魔改Collapse插件(适合不想发双请求的场景)
直接拉Solr 7.7.2的CollapseQParser源码改,加个白名单逻辑就行,代码改动量很小:
- 新增自定义参数比如
collapse.facet.before.fields,值传需要提前算分面的字段名,多个用逗号分隔 - 把原来全局判断是否走折叠前分面的逻辑改成分字段判断:分面字段命中白名单的,用未折叠的全量结果集算聚合,没命中的继续用折叠后的结果集算
- 编译打包后替换掉Solr自带的collapse组件jar包,重启节点就能用,核心逻辑改动不超过50行。
避坑提醒
别想着用join查询、嵌套文档路由代替Collapse做折叠,Solr 7.7.2里join的性能比Collapse差一个量级,碰到多值字段折叠的场景,算出来的结果还不准。
内容的提问来源于stack exchange,提问作者hades512k
相关产品推荐
相关产品推荐

