Solr查询:块连接查询解析器
有两个支持块连接的查询解析器。
这些解析器允许索引和搜索已作为嵌套文档索引的关系内容。
以下查询解析器的示例用法假设已索引了以下文档:
1 | <add> |
块连接子文档查询解析器
此解析器包装一个匹配某些父文档的查询并返回这些文档的子文档。
此解析器的语法是:q={!child of=<blockMask>}<someParents>。
- 内部从属查询字符串(
someParents)必须是一个将匹配某些父文档的查询 of参数必须是一个用作块掩码的查询字符串——通常是匹配所有可能父文档集合的查询
结果查询将匹配所有不匹配<blockMask>查询并且是<someParents>匹配文档的子文档(或后代)的文档。
使用上面的示例文档,我们可以构建一个查询,如q={!child of="content_type:parent"}title:lucene。
我们只得到一个文档作为响应:
1 | <result name="response" numFound="1" start="0"> |
注意: someParents的查询必须匹配块掩码匹配文档的严格子集,否则您的查询可能导致错误:
1 | Parent query must not match any docs besides parent filter. |
如果遇到这种类型的错误,您可以搜索q=+(someParents) -(blockMask)来找到原因。
过滤和标记
{!child}还支持filters和excludeTags本地参数,如下所示:
1 | ?q={!child of=<blockMask> filters=$parentfq excludeTags=certain}<someParents> |
这等同于:
1 | q={!child of=<blockMask>}+<someParents> +BRAND:Foo +NAME:Bar |
注意在filters中引用查询的”$”语法;逗号分隔的标签excludeTags允许通过标记排除某些查询。
总体思路类似于在分面中排除fq。
注意,过滤应用于从属子句(<someParents>),并且交集结果连接到子文档。
所有子文档语法
当省略从属子句(<someParents>)时,它被解析为子文档的_分段_和_缓存_过滤器。
更准确地说,q={!child of=<blockMask>}等同于q=*:* -<blockMask>。
块连接父文档查询解析器
此解析器接受一个匹配子文档的查询并返回它们的父文档。
此解析器的语法类似于child解析器:q={!parent which=<blockMask>}<someChildren>。
- 内部从属查询字符串(
someChildren)必须是一个将匹配某些子文档的查询 which参数必须是一个用作块掩码的查询字符串——通常是匹配所有可能父文档集合的查询
结果查询将匹配所有匹配<blockMask>查询并且是<someChildren>匹配文档的父文档(或祖先)的文档。
再次使用上面的示例文档,我们可以构建一个查询,如q={!parent which="content_type:parent"}comments:SolrCloud。
我们得到这个文档作为响应:
1 | <result name="response" numFound="1" start="0"> |
注意: someChildren的查询不得匹配块掩码匹配的任何文档,否则您的查询可能导致错误:
1 | Child query must not match same docs with parent filter. |
您可以搜索q=+(blockMask) +(someChildren)来找到原因。
过滤和标记
{!parent}查询支持filters和excludeTags本地参数,如下所示:
1 | ?q={!parent which=<blockMask> filters=$childfq excludeTags=certain}<someChildren> |
这等同于:
1 | q={!parent which=<blockMask>}+<someChildren> +COLOR:Red +SIZE:XL |
注意在filters中引用查询的”$”语法。excludeTags中的逗号分隔标签允许通过标记排除某些查询。
总体思路类似于在分面中排除fq。
注意过滤首先应用于从属子句(<someChildren>),然后交集结果连接到父文档。
使用块连接父查询解析器评分
您可以选择使用score本地参数返回从属查询的分数。
用于此参数的值定义聚合类型,包括avg(平均)、max(最大)、min(最小)、total(总和)。
隐式默认值是none,返回0.0。
所有父文档语法
当省略从属子句(<someChildren>)时,它被解析为所有父文档的_分段_和_缓存_过滤器,或者更准确地说,q={!parent which=<blockMask>}等同于q=<blockMask>。
块掩码:of和which本地参数
指定为of或which参数(取决于使用的解析器)的”块掩码”查询的目的是识别索引中应被视为”父文档”_(或其祖先)_的所有文档集合,以及哪些文档应被视为”子文档”。
这很重要,因为在”磁盘上”索引中,关系被扁平化为文档”块”,所以需要of / which参数作为对平面文档块的”掩码”来识别每个层次关系的边界。
在上面的示例查询中,我们能够使用非常简单的doc_type:parent块掩码,因为我们的数据非常简单:每个文档要么是parent要么是child。
因此这个查询字符串很容易区分我们的_所有_文档。
一个常见的错误是尝试使用比所有父文档集合更严格的which参数,以过滤匹配的父文档,如这个错误示例:
1 | // 错误!不要使用! |
这种类型的查询经常不会按您期望的方式工作。
由于which参数只识别_一些_”父”文档,结果查询可能匹配不应该匹配的”父”文档,因为它会错误地将所有不匹配which="title:join"块掩码的文档识别为索引中下一个”父”文档(匹配此掩码)的子文档。
当将父/子文档与没有子文档_并且不匹配用于识别”父”文档的查询_的”简单”文档混合时,可能出现类似的问题情况。例如,如果我们将以下文档添加到现有的父/子示例文档中:
1 | <add> |
…那么我们简单的doc_type:parent块掩码将不再足够。
我们需要使用*:* -doc_type:child或doc_type:(simple parent)来防止我们的”简单”文档被错误地视为相邻”父”文档的”子”文档。
搜索嵌套文档部分包含使用非平凡文档层次结构指定块掩码查询的更详细示例。