Solr如何查询获取每个docid对应的最新版本文档?
Solr查询每个docid对应最新版本文档的实现方案
现有存储的文档示例如下:
{docid:1,version:1} {docid:1,version:2} {docid:2,version:1} {docid:2,version:2} {docid:2,version:3} {docid:3,version:1} {docid:3,version:2}
期望输出每个docid的最高version文档:
{docid:1,version:2} {docid:2,version:3} {docid:3,version:2}
方案1:使用Field Collapsing(字段分组)功能(最常用)
这是Solr原生支持的专门针对这类分组取Top N的功能,实现成本最低,不需要修改现有数据结构:
前提条件
- docid、version字段为已索引、可排序字段,version字段需为数值类型(int/long)避免排序异常
核心查询参数
group=true group.field=docid group.sort=version desc group.limit=1 # 可选参数:开启后返回结果结构和普通查询一致,直接在docs列表返回目标文档,无需额外解析分组嵌套结构 group.main=true
直接拼接以上参数到普通查询请求中即可得到预期结果。
方案2:使用JSON Facet Top Hits功能(适合需要同步做聚合统计的场景)
如果你的查询同时需要做其他维度的统计分析,可以用Solr 7+支持的JSON Facet功能一次查询拿到分组结果和统计数据:
核心参数
json.facet={ "docid_groups": { "terms": { "field": "docid", "limit": -1 # 全量返回所有docid分组,按需调整大小 }, "facet": { "latest_doc": { "top": { "sort": "version desc", "limit": 1, "field": "*" } } } } }
解析返回结果中每个分组的latest_doc字段即可拿到对应最新版本文档。
方案3:写入预处理方案(适合读请求占比高的场景)
如果该查询是业务高频查询,不想每次查询都做分组计算,可以在写入阶段做预处理,提升查询性能:
- 方案3.1:不需要保留历史版本的场景,直接将docid设为Solr文档唯一键,写入高版本文档时自动覆盖低版本文档,查询时无需任何额外参数,直接查询即可得到全量最新文档
- 方案3.2:需要保留历史版本的场景,新增
is_latest布尔类型字段,写入新版本文档时,同步将同docid下旧版本文档的is_latest字段更新为false,新版本设为true。查询时直接加过滤条件fq=is_latest:true即可,查询性能远高于实时分组计算。
注意事项
- 若docid基数极大,使用分组查询时注意调整
group.offset、group.limit参数避免分页异常 - version字段禁止使用字符串类型,否则会出现版本10排序在2之前的异常问题
内容的提问来源于stack exchange,提问作者user3309305
相关产品推荐
相关产品推荐

