根据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
分析器的定义很重要,因为地址字段没有在查询中使用,但如果有人想看到它,可以包含它。
答案 0 :(得分:13)
这实际上是NEST中的一个错误
NEST如何帮助翻译布尔查询的前提:
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发现播放中的布尔描述符仅由should
组成时,NEST也会对should clauses
做同样的事情。这是因为boolquery并不完全遵循您对编程语言所期望的相同布尔逻辑。
总结后者:
term || term || term
变为
bool
should
term
term
term
但是
term1 && (term2 || term3 || term4)
不会成为
bool
must
term1
should
term2
term3
term4
这是因为一旦布尔查询具有must子句,就应该开始充当提升因子。所以在前面你可以得到仅包含term1
的结果,这显然不是你想要的严格布尔意义上的输入。
NEST因此将此查询重写为
bool
must
term1
bool
should
term2
term3
term4
现在,bug出现在你的情况中你有这个
bool(should=term1, term2, minimum_should_match=2) || term3
NEST确定OR操作的两端只包含should子句,并且它们将它们连接在一起,这将给第一个布尔查询的minimum_should_match
参数赋予不同的含义。
我刚推出了一个修复程序,这将在下一个版本0.11.8.0
感谢您抓住这个!