我正在使用 OpenSearch 查询数据库中的文档,目前我正在执行此搜索(我使用的是 default_operator=AND
,“”之间的术语是术语 1 4 和 5是我省略的两个单词的术语,即:“foo bar”):
“术语 1”、术语 2、术语 3、“术语 4”或“术语 5”
但是当我查看结果时,有些文档只有 "term 1"term2 term3
。如果我添加括号,情况会发生变化,此搜索会返回我想要的内容:
(“术语 1” term2 term3 “术语 4”) OR (“术语 5”)
这些查询的结果之间存在差异有什么意义吗?
我还尝试将“term 4”位置更改为:
“术语 1”“术语 4”术语 2 术语 3 或“术语 5”
结果也与第一个查询的结果不同,对我来说这没有意义。
这是一个几乎完整的查询的示例:
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"query_string": {
"query": "\"term 1\" term2 term3 \"term 4\" OR \"term 5\"",
"fields": [
"my_field.analyzed"
],
"default_operator": "AND",
"boost": 0.1
}
},
{
"query_string": {
"query": "\"term 1\" term2 term3 \"term 4\" OR \"term 5\"",
"fields": [
"my_field_2",
"my_field_3"
],
"boost": 0.5
}
}
]
}
},
{
"exists": {
"field": "my_field"
}
}
],
最佳答案
值得注意的是 bool 运算符 DO NOT follow the usual precedence rules ( another example here 和 some more thoughts here )。
如果您是 JavaCC 爱好者,您还可以查看 compiler definition用于 Lucene 的查询字符串解析器。您将看到查询是按顺序解析的,即没有您期望的优先级,除非正确指定括号。
最后一个链接的主要收获是,您不需要考虑 bool 运算,而需要考虑可选、必需(即 +
)和禁止(即 -
)
使用Validate API ,你可以看到Lucene端执行了什么。例如,下面的第一个查询
{
"query_string": {
"query": "\"term 1\" term2 term3 \"term 4\" OR \"term 5\"",
"fields": [
"my_field.analyzed"
],
"default_operator": "AND",
"boost": 0.1
}
},
执行为
(
+my_field.analyzed:term 1
+my_field.analyzed:term2 term3
my_field.analyzed:term 4
my_field.analyzed:term 5
)^0.1
所以,
第 1 项
为必填项term2 term3
(两者连接在一起)是必需的术语 4
和术语 5
是可选的
关于第二个查询,
{
"query_string": {
"query": "\"term 1\" term2 term3 \"term 4\" OR \"term 5\"",
"fields": [
"my_field_2",
"my_field_3"
],
"boost": 0.5
}
}
它的执行方式为
+(
+(my_field_2:term 1 | my_field_3:term 1)
+(my_field_2:term2 term3 | my_field_3:term2 term3)
(my_field_2:term 4 | my_field_3:term 4)
(my_field_2:term 5 | my_field_3:term 5)
)^0.1
所以:
term 1
必须出现在my_field_2
或my_field_3
中term2 term3
必须出现在my_field_2
或my_field_3
term 4
可以出现在my_field_2
或my_field_3
term 5
可以出现在my_field_2
或my_field_3
- 以上至少一项必须匹配(即最开始的初始
+
)
关于elasticsearch - 使用括号时 OpenSearch 返回不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76623293/