Chr*_*ris 1 solr faceted-search solr4
我正在为我们的网站开发产品过滤器,但在使用“facet.missing = true”时遇到了一些困难。
我知道我应该使用像“fq=-facetField:[* TO *]”这样的查询过滤器来将结果过滤到缺少该字段的产品。
我为我的应用程序构建了一个全局过滤器助手,它为所有查询动态构建 fq 参数,以防止任何人错过基于用户权限的过滤器,它基本上如下所示(php):
$params['fq'] = sprintf('((%s) AND (%s))', $custom, $system);
Run Code Online (Sandbox Code Playgroud)
其中 $system 是基于全局权限的过滤器,它可能看起来像(不是实际但相似):
(isdiscontinued:0 AND ishidden:0 AND contract:3)
Run Code Online (Sandbox Code Playgroud)
$custom 包含用户通过 UI 构建的实际过滤器查询。假设笔记本蓝牙过滤器的名称为 fq_bluetooth,其值为:No、Yes 或值丢失。这将使最终的 fq 看起来像:
((-fq_bluetooth:[* TO *]) AND ((isdiscontinued:0 AND ishidden:0 AND contract:3)))
Run Code Online (Sandbox Code Playgroud)
但是,这会为我为此类别发送的查询返回 0 个产品。
如果我将过滤器查询修改为:
((fq_bluetooth:[* TO *]) AND ((isdiscontinued:0 AND ishidden:0 AND contract:3)))
Run Code Online (Sandbox Code Playgroud)
然后我得到了 Yes + No 计数的预期结果,不考虑未指定的。
我应该如何格式化过滤器查询以使其正常工作?
[编辑]
我可能还想结合这些方面,并且可能只过滤没有蓝牙的产品或未指定蓝牙的产品。所以也许像这样(当然这也不起作用):
((-fq_bluetooth:[* TO *] OR fq_bluetooth:"No") AND ((isdiscontinued:0 AND ishidden:0 AND contract:3)))
Run Code Online (Sandbox Code Playgroud)
我注意到 debugQuery 打开,我看到一个过滤器查询,如:
fq_bluetooth:("No" OR -[* TO *])
Run Code Online (Sandbox Code Playgroud)
被解析为:
fq_bluetooth:No -fq_bluetooth:[* TO *]
Run Code Online (Sandbox Code Playgroud)
我在解析的查询中没有看到 OR - 从我的研究来看,fq 参数查询不支持 OR 运算符(??)。
也许 OR 正在工作,但由于否定查询本身似乎失败了,也许这就是为什么我在这样组合时看不到 OR 工作的原因。
去掉不必要的括号,将过滤器查询拆分为两个过滤器查询,一个用于系统限制,另一个用于用户生成的过滤。
1) 既然您要满足请求中的两个逻辑要求(安全限制和用户生成的过滤),为什么不用两个过滤查询重写您的查询?
一个用于系统权限,另一个用于从您的应用程序 UI 生成的查询(省略转义):
...fq=isdiscontinued:0 AND ishidden:0 AND contract:3&fq=-fq_bluetooth:[* TO *]
这甚至有助于过滤查询缓存
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": []
}
}
Run Code Online (Sandbox Code Playgroud)
与-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": [...]
}
}
Run Code Online (Sandbox Code Playgroud)
同样,使用两个过滤器查询返回预期结果:
{
"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": [...]
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:这篇文章 清楚地解释了为什么使用括号可能会导致意想不到的结果。报价:
如果顶级 BoolenQuery 在其内部某处包含一个仅包含否定子句的嵌套 BooleanQuery,则不会修改该嵌套查询,并且它(根据定义)不匹配任何文档——如果需要,这意味着外部查询将不匹配。