根据特定字段查询一个或另一个文档

时间:2015-05-13 10:55:59

标签: solr

想象一下SolR索引,其文档与此类似

[
{
    ProductId: 123,
    Contract: abc
},
{
    ProductId: 123,
    Contract: def
},
{
    ProductId: 123
},
{
    ProductId: 567
},
{
    ProductId: 567,
    Contract: bar
}
]
  • 始终包含特定ProductId并且没有Contract
  • 的文档
  • 此外,可能有0到n个文件 Contract

我需要一个查询,在那里我可以使用Contract,并且应该将ProductId s 返回给我具有给定Contract的那个,如果存在,或者根本没有Contract的单个文档。

例如,我将使用Contract: def进行查询(不知何故),它应该给我这个

[
{
    ProductId: 123,
    Contract: def
},
{
    ProductId: 567
}
]
  • Contract:abc的文档是结果的一部分
  • 包含ProductId:123但没有Contract的文档不属于结果
  • 文档ProductId:567是结果的一部分,因为没有包含此ProductIdContractId: def
  • 的文档

换句话说,我需要的是像

  • 每个ProductIdContract:X XOR -Contract*给我一个文件,但不是两个。

1 个答案:

答案 0 :(得分:0)

步骤1 编写您的查询,以便返回没有合同的记录以及所有匹配合同的记录,但具有相应合同的记录得分最高。这解决了您有时希望结果中的项与合同值不匹配的问题:q=Contract:"def" OR (*:* -Contract:[* TO *])(*:* -Contract:[* TO *])匹配没有合同的所有记录,Contract:"def"匹配具有正确合同的记录。匹配Contract:"def"的记录自然应该比没有合同的记录得分高,但是如果有任何问题或者你只是想确定,你可以对该子句Contract:"def"^2添加一个提升。

第2步将<{3}}添加到查询中,并进行配置,以便您只请求任何给定ProductId得分最高记录:< / p>

q=Contract:"def" OR (*:* -Contract:[* TO *])&group=true&group.field=ProductId

这要求ProductId中的schema.xml字段配置为multiValued="false",因为多值字段不能用作组。我还假设您使用的是Result Grouping,要么在solrconfig.xml中设置为默认值,要么在进行查询时添加参数defType=lucene

结果应如下所示:

'grouped'=>{
'ProductId'=>{
  'matches'=>5,
  'groups'=>[{
      'groupValue'=>123,
      'doclist'=>{'numFound'=>3,'start'=>0,'docs'=>[
          {
            'ProductId'=>123,
            'Contract'=>'def'}]
      }},
    {
      'groupValue'=>567,
      'doclist'=>{'numFound'=>2,'start'=>0,'docs'=>[
          {
            'ProductId'=>567}]
      }}]}}}

请注意,结果集中的matchesnumFound值都不会告诉您已返回的组数,但参数rows=XX可用于定义最大数量所需组(在本例中为ProductIds)。