根据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字段都匹配,则记录应包括在结果中。
SocialSecurityNumber
Name.First
Name.Last
当我使用对QueryString的调用中使用的nameOnRecord对象的以下数据执行此查询时:
"socialSecurityNumber":"123456789", "name" : { "first":"ryan", }
结果是拥有SSN的人123456789,以及有姓氏的人ryan。
123456789
ryan
如果我|| ssnQuery从上面的查询中删除,则会得到所有人的名字为“ ryan”。
|| ssnQuery
随着|| 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分析器的定义并不重要,因为查询中未使用地址字段,但是如果有人想查看它,可以将其包括在内。
address
这实际上是NEST中的错误
NEST如何帮助转换布尔查询的先驱:
NEST允许您使用运算符重载轻松创建详细的布尔查询/过滤器,即:
term && term 将导致:
term && term
bool must term term
天真的实现会重写
term && term && term 至
term && term && term
bool must term bool must term term
正如您可以想象的那样,查询变得更加复杂,NEST可以发现这些并将它们结合在一起,从而变得非常笨拙
bool must term term term
同样term && 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并没有完全遵循您希望从编程语言中获得的布尔逻辑。
should
should clauses
总结一下:
term || term || term
变成
bool should term term term
但
term1 && (term2 || term3 || term4) 不会成为
term1 && (term2 || term3 || term4)
bool must term1 should term2 term3 term4
这是因为布尔查询一旦具有must子句,就应该开始作为促进因素。因此,在前面的内容中,您可能会得到仅包含term1此内容的结果,这在严格的布尔输入意义上显然不是您想要的。
term1
为此,NEST将此查询重写为
bool must term1 bool should term2 term3 term4
现在,这个错误开始起作用的地方就是您的情况
bool(should=term1, term2, minimum_should_match=2) || term3NEST标识OR操作的两侧仅包含应该子句,它将它们连接在一起,这将给minimum_should_match第一个布尔查询的参数赋予不同的含义。
bool(should=term1, term2, minimum_should_match=2) || term3
minimum_should_match
我只是为此推送了一个修复程序,它将在下一个版本中修复 0.11.8.0
0.11.8.0
感谢您抓住这个!