elasticsearch - && 和 || 怎么做在 NEST 中构建查询?

标签 elasticsearch nest

根据 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.FirstName.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/

相关文章:

elasticsearch - 日期时间字段的模糊性

c# - Elasticsearch 巢 : Bulk-indexing operation does not make use of specified document IDs

c# - 使用C#客户端Nest进行无辩识的Elasticsearch中的索引编制和全文本搜索

elasticsearch - Elasticsearch多重匹配字段不包含查询字符串

linux - awk 在输出中打印不必要的新行

elasticsearch - 搜索字符串中有数字时,Elasticsearch通配符失败

ElasticSearch 与关系数据库

elasticsearch - 没有异常值的平均值

c# - DynamicDictionary在ElasticSearch 2.0(Elasticsearch.Net)上不再可用

c# - 如何通过使用Nest从Json ElasticSearch获取logType和级别?