【问题标题】:Trouble with negative facet query using solr for missing value使用 solr 查找缺失值的负面方面查询的问题
【发布时间】:2014-08-29 15:55:09
【问题描述】:

我正在为我们的网站开发产品过滤器,但在使用“facet.missing = true”时遇到了一些困难。

我知道我应该使用“fq=-facetField:[* TO *]”之类的查询过滤器将结果过滤到缺少该字段的产品。

我为我的应用程序构建了一个全局过滤器助手,它为所有查询动态构建 fq 参数,以防止任何人错过基于用户权限的过滤器,这些过滤器基本上看起来像这样 (php):

$params['fq'] = sprintf('((%s) AND (%s))', $custom, $system);

其中 $system 是基于全局权限的过滤器,可能看起来像(不是实际但类似):

(isdiscontinued:0 AND ishidden:0 AND contract:3)

$custom 包含用户通过 UI 构建的实际过滤器查询。假设笔记本蓝牙过滤器的名称为 fq_bluetooth,其值为:否、是,或缺少该值。这将使最终的 fq 看起来像:

((-fq_bluetooth:[* TO *]) AND ((isdiscontinued:0 AND ishidden:0 AND contract:3)))

但是,对于我为此类别发送的查询,这会返回 0 个产品。

如果我将过滤器查询修改为:

((fq_bluetooth:[* TO *]) AND ((isdiscontinued:0 AND ishidden:0 AND contract:3)))

然后我得到了 Yes + No 计数的预期结果,忽略未指定的。

我应该如何格式化过滤器查询以使其正常工作?

[编辑]

我可能还想组合这些方面,并且可能只过滤没有蓝牙的产品或未指定蓝牙的产品。所以也许像这样(当然也不起作用):

((-fq_bluetooth:[* TO *] OR fq_bluetooth:"No") AND ((isdiscontinued:0 AND ishidden:0 AND contract:3)))

我注意到 debugQuery 开启时,我看到一个过滤器查询,例如:

fq_bluetooth:("No" OR -[* TO *])

被解析为:

fq_bluetooth:No -fq_bluetooth:[* TO *]

我在解析后的查询中没有看到 OR - 根据我的研究,fq 参数查询不支持 OR 运算符(??)。

也许 OR 正在工作,但由于否定查询本身似乎失败了,也许这就是为什么我在这样组合时看不到 OR 工作的原因。

【问题讨论】:

    标签: solr solr4 faceted-search


    【解决方案1】:

    删除不必要的括号并将您的过滤器查询拆分为两个过滤器查询,一个用于系统限制,一个用于用户生成的过滤。

    1) 既然您想满足请求中的两个逻辑要求(安全限制和用户生成的过滤),为什么不用两个过滤查询重写您的查询?

    一个用于系统权限,另一个用于从您的应用 UI 生成的查询(转义省略):

    ...fq=isdiscontinued:0 AND ishidden:0 AND contract:3&fq=-fq_bluetooth:[* TO *]

    这甚至可以帮助filter query caching

    2)至于您的具体查询问题,通过实验,括号的存在似乎正在改变预期结果。用本地实例做测试,我有以下,如果我使用你的语法,((-ProcedeImageElectronique:[* TO *]) AND (Pays:France AND GrandeCategorie:FILM)) 返回 0 结果:

    {
      "responseHeader": {
        "status": 0,
        "QTime": 1,
        "params": {
          "facet": "off",
          "indent": "true",
          "q": "*:*",
          "wt": "json",
          "fq": "((-ProcedeImageElectronique:[* TO *]) AND (Pays:France AND GrandeCategorie:FILM))"
        }
      },
      "response": {
        "numFound": 0,
        "start": 0,
        "maxScore": 0,
        "docs": []
      }
    }
    

    与导致预期行为的-ProcedeImageElectronique:[* TO *] AND Pays:France AND GrandeCategorie:FILM 相比:

    {
      "responseHeader": {
        "status": 0,
        "QTime": 1,
        "params": {
          "facet": "off",
          "indent": "true",
          "q": "*:*",
          "wt": "json",
          "fq": "-ProcedeImageElectronique:[* TO *] AND Pays:France AND GrandeCategorie:FILM"
        }
      },
      "response": {
        "numFound": 1733,
        "start": 0,
        "maxScore": 1,
        "docs": [...]
      }
    }
    

    同样,使用两个过滤器查询返回预期结果:

    {
      "responseHeader": {
        "status": 0,
        "QTime": 0,
        "params": {
          "facet": "off",
          "indent": "true",
          "q": "*:*",
          "wt": "json",
          "fq": [
            "-ProcedeImageElectronique:[* TO *]",
            "GrandeCategorie:FILM AND Pays:France"
          ]
        }
      },
      "response": {
        "numFound": 1733,
        "start": 0,
        "maxScore": 1,
        "docs": [...]
      }
    }
    

    编辑:this post 清楚地解释了为什么使用括号可能会导致意外结果。引用:

    如果顶层 BoolenQuery 在其内部某处包含一个嵌套 仅包含否定子句的 BooleanQuery,即嵌套查询 不会被修改,并且它(根据定义)不匹配任何文档 -- 如果需要,则表示外部查询将不匹配。

    【讨论】:

    • 感谢 qux 的回复!我设法使我的查询像: fq=-fq_bluetooth:[* TO * ]&fq=(isdiscontinued:0 AND ishidden:0 AND contract:3) (顺便说一句,系统过滤器还有更多内容,包括更多组和ORed 元素)。虽然查询有效,但当我想添加多个条件时它会失败: fq=fq_bluetooth:("No" OR -[* TO *])&fq=(isdiscontinued:0 AND ishidden:0 AND contract:3)
    • 你试过不带父母吗?即 fq=fq_bluetooth:"No" OR -[* TO *]
    • 问题是否定子句。像这样尝试:fq=fq_bluetooth:No OR (-fq_bluetooth:[* TO *] *:* ) 这对我有用。因此,每当您想匹配缺失值时,请在您的应用查询生成器中使用 (-fieldname:[* TO *] *:* )
    猜你喜欢
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2012-04-11
    • 1970-01-01
    • 2011-11-10
    相关资源
    最近更新 更多