根据 http://nest.azurewebsites.net/concepts/writing-queries.html , && 和 ||运算符可用于使用 NEST 库组合两个查询以与 Elastic Search 通信。
我设置了以下查询:
var ssnQuery = Query<NameOnRecordDTO>.Match(
q => q.OnField(f => f.SocialSecurityNumber).QueryString(nameOnRecord.SocialSecurityNumber).Fuzziness(0)
);
然后结合 Bool 查询,如下所示:
var result = client.Search<NameOnRecordDTO>(
body => body.Query(
query => query.Bool(
bq => bq.Should(
q => q.Match(
p => p.OnField(f => f.Name.First)
.QueryString(nameOnRecord.Name.First).Fuzziness(fuzziness)
),
q => q.Match(p => p.OnField(f => f.Name.Last)
.QueryString(nameOnRecord.Name.Last).Fuzziness(fuzziness)
)
).MinimumNumberShouldMatch(2)
) || ssnQuery
)
);
我认为这个查询的意思是,如果 SocialSecurityNumber
匹配,或者 Name.First
和 Name.Last
字段匹配,那么记录应该包含在结果中。
当我使用调用 QueryString 时使用的 nameOnRecord 对象的以下数据执行此查询时:
"socialSecurityNumber":"123456789",
"name" : {
"first":"ryan",
}
结果是 SSN 为 123456789
的人,以及名字为 ryan
的任何人。
如果我删除 || ssnQuery
从上面的查询中,我得到了所有名字是“ryan”的人。
使用|| ssnQuery
就位和以下查询:
{
"socialSecurityNumber":"123456789",
"name" : {
"first":"ryan",
"last": "smith"
}
}
我似乎找到了 SSN 为 123456789 的人以及名字为“ryan”或姓氏为“smith”的人。
所以看起来没有添加|| ssnQuery
正在产生我预期的效果,我不知道为什么。
这里是相关对象索引的定义:
"nameonrecord" : {
"properties": {
"name": {
"properties": {
"name.first": {
"type": "string"
},
"name.last": {
"type": "string"
}
}
},
"address" : {
"properties": {
"address.address1": {
"type": "string",
"index_analyzer": "address",
"search_analyzer": "address"
},
"address.address2": {
"type": "string",
"analyzer": "address"
},
"address.city" : {
"type": "string",
"analyzer": "standard"
},
"address.state" : {
"type": "string",
"analyzer": "standard"
},
"address.zip" : {
"type" : "string",
"analyzer": "standard"
}
}
},
"otherName": {
"type": "string"
},
"socialSecurityNumber" : {
"type": "string"
},
"contactInfo" : {
"properties": {
"contactInfo.phone": {
"type": "string"
},
"contactInfo.email": {
"type": "string"
}
}
}
}
}
我认为 address
分析器的定义不重要,因为地址字段未在查询中使用,但如果有人想查看,可以将其包括在内。
最佳答案
这实际上是 NEST 中的一个错误
NEST 如何帮助翻译 bool 查询的先驱:
NEST 允许您使用运算符重载轻松创建冗长的 bool 查询/过滤器,即:
term && term
将导致:
bool
must
term
term
一个天真的实现会重写
term && term && term
到
bool
must
term
bool
must
term
term
正如您所想象的那样,查询变得越复杂,NEST 就可以发现这些并将它们连接在一起成为
bool
must
term
term
term
同样 term && term && term && !term
简单地变成:
bool
must
term
term
term
must_not
term
现在如果在前面的例子中你像这样直接传入一个booleanquery
bool(must=term, term, term) && !term
它仍然会生成相同的查询。当 NEST 发现游戏中的 bool 描述符仅由 should 子句
组成时,它也会对 should
执行相同的操作。这是因为 boolquery 并不完全遵循您期望从编程语言中获得的相同 bool 逻辑。
总结一下后者:
术语 ||术语 ||术语
成为
bool
should
term
term
term
但是
term1 && (term2 || term3 || term4)
不会变成
bool
must
term1
should
term2
term3
term4
这是因为一旦 bool 查询具有 must 子句,它就应该开始充当增强因子。所以在之前你可以得到只包含 term1
的结果,这显然不是你想要的输入的严格 bool 意义上的结果。
NEST 因此将此查询重写为
bool
must
term1
bool
should
term2
term3
term4
现在 bug 开始发挥作用的地方是你的情况你有这个
bool(should=term1, term2, minimum_should_match=2) || term3
NEST 识别出 OR 操作的两边只包含 should 子句,并将它们连接在一起,这会给第一个 bool 查询的 minimum_should_match
参数赋予不同的含义。
我刚刚推送了一个修复程序,这将在下一个版本 0.11.8.0
感谢收看这个!
关于elasticsearch - && 和 || 怎么做在 NEST 中构建查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19591204/