块连接查询解析器

有两个查询解析器支持块连接。这些解析器允许对已 索引为嵌套文档 的关系内容进行索引和搜索。

下面查询解析器的示例用法假定已索引以下文档

<add>
  <doc>
    <field name="id">1</field>
    <field name="content_type">parent</field>
    <field name="title">Solr has block join support</field>
    <doc>
      <field name="id">2</field>
      <field name="content_type">child</field>
      <field name="comments">SolrCloud supports it too!</field>
    </doc>
  </doc>
  <doc>
    <field name="id">3</field>
    <field name="content_type">parent</field>
    <field name="title">New Lucene and Solr release</field>
    <doc>
      <field name="id">4</field>
      <field name="content_type">child</field>
      <field name="comments">Lots of new features</field>
    </doc>
  </doc>
</add>

块连接子查询解析器

此解析器包装与某些父文档匹配并返回这些文档的子文档的查询。

此解析器的语法为:q={!child of=<blockMask>}<someParents>

  • 内部从属查询字符串 (someParents) 必须是与某些父文档匹配的查询

  • of 参数必须是作为 块掩码 使用的查询字符串,通常是与所有可能的父文档集匹配的查询

结果查询将匹配所有 匹配 <blockMask> 查询且是 <someParents> 匹配的文档的子文档(或后代文档)。

使用上述示例文档,我们可以构造如 q={!child of="content_type:parent"}title:lucene 的查询。我们仅在响应中获取一个文档

<result name="response" numFound="1" start="0">
  <doc>
    <str name="id">4</str>
    <arr name="content_type"><str>child</str></arr>
    <str name="comments">Lots of new features</str>
  </doc>
</result>

someParents 的查询必须匹配 块掩码 匹配的文档的严格子集,否则查询可能会导致错误

Parent query must not match any docs besides parent filter.
Combine them as must (+) and must-not (-) clauses to find a problem doc.

如果您遇到此类错误,则可以搜索 q=+(someParents) -(blockMask) 以查找原因。

过滤和标记

{!child} 还支持以下 filtersexcludeTags 本地参数

?q={!child of=<blockMask> filters=$parentfq excludeTags=certain}<someParents>
&parentfq=BRAND:Foo
&parentfq=NAME:Bar
&parentfq={!tag=certain}CATEGORY:Baz

这等效于

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。我们得到此文档作为响应

<result name="response" numFound="1" start="0">
  <doc>
    <str name="id">1</str>
    <arr name="content_type"><str>parent</str></arr>
    <arr name="title"><str>Solr has block join support</str></arr>
  </doc>
</result>

someChildren 的查询 绝不能 匹配 块掩码 匹配的任何文档,否则您的查询可能会导致错误

Child query must not match same docs with parent filter.
Combine them as must clauses (+) to find a problem doc.

您可以搜索 q=+(blockMask) +(someChildren) 以查找原因。

过滤和标记

{!parent} 查询支持以下 filtersexcludeTags 本地参数

?q={!parent which=<blockMask> filters=$childfq excludeTags=certain}<someChildren>
&childfq=COLOR:Red
&childfq=SIZE:XL
&childfq={!tag=certain}PRINT:Hatched

这等效于

q={!parent which=<blockMask>}+<someChildren> +COLOR:Red +SIZE:XL

请注意 filters 中的 $ 语法用于引用查询。excludeTags 中用逗号分隔的标记允许通过标记排除某些查询。总体思路类似于 在分面中排除 fq。请注意,过滤首先应用于从属子句 (<someChildren>),然后将交集结果与父文档连接。

使用块连接父查询解析器进行评分

您可以选择使用 score 本地参数返回从属查询的分数。用于此参数的值定义聚合类型,包括 avg(平均值)、max(最大值)、min(最小值)、total (sum)。隐式默认值为 none,它返回 0.0

所有父文档语法

当从属子句 (<someChildren>) 被省略时,它将被解析为所有父文档的分段缓存的过滤器,或更确切地说,q={!parent which=<blockMask>} 等效于 q=<blockMask>

块掩码:ofwhich 本地参数

ofwhich 参数(取决于所使用的解析器)指定“块掩码”查询的目的是识别索引中所有应视为“父级”(或其祖先)的文档集,以及应视为“子级”的文档。这很重要,因为在“磁盘上”索引中,关系被展平为文档“块”,因此需要 of / which 参数作为针对平面文档块的“掩码”,以识别每个层次关系的边界。

在上面的示例查询中,我们能够使用非常简单的 doc_type:parent 块掩码,因为我们的数据非常简单:每个文档要么是 parent,要么是 child。因此,此查询字符串很容易区分我们所有的文档。

一个常见的错误是尝试使用比所有父文档集更具限制性的 which 参数,以过滤匹配的父级,如下面的错误示例所示

// BAD! DO NOT USE!
q={!parent which="title:join"}comments:support

此类查询通常不会按您预期的方式工作。由于 which 参数仅识别一些“父级”文档,因此生成的查询可能会匹配它不应该匹配的“父级”文档,因为它会错误地将匹配 which="title:join" 块掩码的所有文档识别为索引中下一个“父级”文档(确实匹配此掩码)的子级。

当将父级/子级文档与没有子级的“简单”文档(并且不匹配用于识别“父级”文档的查询)混合时,可能会出现类似的问题。例如,如果我们将以下文档添加到我们现有的父级/子级示例文档中

<add>
  <doc>
    <field name="id">0</field>
    <field name="content_type">plain</field>
    <field name="title">Lucene and Solr are cool</field>
  </doc>
</add>

…​那么我们简单的 doc_type:parent 块掩码将不再足够。相反,我们需要使用 *:* -doc_type:childdoc_type:(simple parent) 来防止我们的“简单”文档被错误地视为相邻“父级”文档的“子级”。

搜索嵌套子文档 部分包含更多有关使用具有非平凡文档层次结构指定块掩码查询的详细示例。