使用solr进行缺少值的负方面查询时出现问题

使用solr进行缺少值的负方面查询时出现问题,solr,solr4,faceted-search,Solr,Solr4,Faceted Search,我正在为我们的网站设计一个产品过滤器,在使用facet.missing=true时遇到了一些困难 我知道我应该使用像fq=-facetField:[*to*]这样的查询过滤器来将结果过滤到缺少该字段的产品 我已经为我的应用程序构建了一个全局过滤器帮助器,它为所有查询动态构建fq参数,以防止遗漏任何基于用户权限的过滤器,这些过滤器本质上类似于以下php: $params['fq'] = sprintf('((%s) AND (%s))', $custom, $system); 其中,$syste

我正在为我们的网站设计一个产品过滤器,在使用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)))
然后我得到了可以预期的是+否计数的结果,忽略了未指定的

我应该如何格式化筛选器查询以使其正常工作

[编辑]

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

((-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工作的原因。

去掉不必要的括号,将筛选查询拆分为两个筛选查询,一个用于系统限制,另一个用于用户生成的筛选

1既然您希望在请求安全限制和用户生成的筛选中满足两个逻辑要求,为什么不使用两个筛选查询重写查询

一个用于系统权限,另一个用于从应用程序UI生成的查询:

…fq=isdiscontinued:0和ishidden:0以及contract:3&fq=-fq\u蓝牙:[*到*]

这甚至有助于解决问题

2至于您的特定查询问题,通过实验,括号的存在似乎改变了预期结果。使用本地实例进行测试时,如果我使用您的语法,-ProcedeImageElectronique:[*TO*]并支付:France和GrandCategorie: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": []
  }
}
与-ProcedImageElectronique:[*至*]和Pays:France和GrandCategorie: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": [...]
  }
}
编辑:清楚地解释了为什么使用括号可能导致意外结果。引述:

如果顶级BoolenQuery中包含嵌套的 只包含否定子句的布尔查询,即嵌套查询 不会被修改,而且根据定义,它与任何文档都不匹配 -如果需要,这意味着外部查询将不匹配


删除不必要的括号,并将筛选查询拆分为两个筛选查询,一个用于系统限制,另一个用于用户生成的筛选

1既然您希望在请求安全限制和用户生成的筛选中满足两个逻辑要求,为什么不使用两个筛选查询重写查询

一个用于系统权限,另一个用于从应用程序UI生成的查询:

…fq=isdiscontinued:0和ishidden:0以及contract:3&fq=-fq\u蓝牙:[*到*]

这甚至有助于解决问题

2至于您的特定查询问题,通过实验,括号的存在似乎改变了预期结果。使用本地实例进行测试时,如果我使用您的语法,-ProcedeImageElectronique:[*TO*]并支付:France和GrandCategorie: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": []
  }
}
与-ProcedImageElectronique:[*至*]和Pays:France和GrandCategorie: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": [...]
  }
}
编辑:清楚地解释了为什么使用括号可能导致意外结果。引述:

如果顶级BoolenQuery中包含嵌套的 只包含否定子句的布尔查询,即嵌套查询 不会被修改,而且根据定义,它与任何文档都不匹配 -如果需要,这意味着外部查询将不匹配


感谢您对qux的回复!我曾尝试过这样做:fq=-fq_bluetooth:[*to*]&fq=isdiscontinued:0和ishidden:0和contract:3。顺便说一句,系统筛选器还有更多内容,包括更多组和OR元素。当查询工作时,它将失败
en我想添加多个条件:fq=fq_蓝牙:否或-[*to*]&fq=isdiscontinued:0和ishdden:0和contract:3您是否尝试过不使用Parentshis?i、 e.fq=fq\u蓝牙:否或-[*TO*]问题在于否定子句。像这样尝试:fq=fq\u蓝牙:否或-fq\u蓝牙:[*到*]*:*这对我很有用。因此,每当您想要匹配缺少的值时,请在应用程序查询生成器库中为响应qux使用-fieldname:[*到*]*:*!我曾尝试过这样做:fq=-fq_bluetooth:[*to*]&fq=isdiscontinued:0和ishidden:0和contract:3。顺便说一句,系统筛选器还有更多内容,包括更多组和OR元素。当查询工作时,当我想添加多个条件时,它将失败:fq=fq_bluetooth:No或-[*to*]&fq=isdiscontinued:0和ishidden:0和contract:3您是否尝试过不使用ParentShis?i、 e.fq=fq\u蓝牙:否或-[*TO*]问题在于否定子句。像这样尝试:fq=fq\u蓝牙:否或-fq\u蓝牙:[*到*]*:*这对我很有用。因此,每当您想要匹配缺少的值时,请在应用程序查询生成器中使用-fieldname:[*到*]*:*