Solr嵌套文档查询:如何检索同时含多个指定子文档的父文档
Solr匹配多条件嵌套子文档的父查询实现方案
Solr原生支持该查询场景。
直接在单个{!parent}块内用AND拼接子文档条件不生效的核心原因是匹配粒度错误:单个{!parent}包裹的子查询以单个子文档为匹配单位,要求同一个子文档同时满足所有AND条件。而需求是父文档下存在多个不同子文档分别命中对应条件,匹配粒度是父文档层面的结果交集,不是单个子文档的属性交集。
实现方案
基础写法:多Parent查询块AND拼接
将每个子文档的匹配条件单独包裹在{!parent}查询块中,在父查询层面对多个块的返回结果取交集即可,语法示例:
{!parent which='type:maindoc'}nested_type:nestedType1 AND {!parent which='type:maindoc'}nested_type:nestedType2
执行逻辑:
- 第一个
{!parent}块筛选出所有携带nestedType1类型子文档的主文档 - 第二个
{!parent}块筛选出所有携带nestedType2类型子文档的主文档 - 两个结果集的交集就是同时拥有两类子文档的目标主文档
性能优化写法:拆分Filter Query
如果匹配的子文档条件多、查询频次高,可以把每个子文档匹配条件拆为独立的过滤查询(fq),借助Solr的Filter缓存机制降低重复查询的开销,示例:
q=*:* fq={!parent which='type:maindoc' v=$cond1} fq={!parent which='type:maindoc' v=$cond2} cond1=nested_type:nestedType1 cond2=nested_type:nestedType2
错误写法说明
之前使用的写法属于典型的粒度误用:
// 错误:要求单个子文档的nested_type同时为两个互斥值,永远无匹配结果 {!parent which='type:maindoc'} nested_type:nestedType1 AND nested_type:nestedType2
该写法的匹配逻辑是查找存在一个子文档,它的nested_type字段同时等于nestedType1和nestedType2,现实中不存在符合该条件的子文档,因此无法返回正确结果。
注意:使用Block Join系列查询(parent/child)前,需要确保嵌套文档在索引时是和父文档作为同一个文档块(Document Block)提交的,若将嵌套字段作为普通多值字段扁平化存储,这类查询无法正常工作。
内容的提问来源于stack exchange,提问作者Mikalai Ushanau
相关产品推荐
相关产品推荐

