当前位置: 首页 > 面试题库 >

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

祁飞翰
2023-03-14
问题内容

根据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如何帮助转换布尔查询的先驱:

NEST允许您使用运算符重载轻松创建详细的布尔查询/过滤器,即:

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

现在,这个错误开始起作用的地方就是您的情况

bool(should=term1, term2, minimum_should_match=2) || term3NEST标识OR操作的两侧仅包含应该子句,它将它们连接在一起,这将给minimum_should_match第一个布尔查询的参数赋予不同的含义。

我只是为此推送了一个修复程序,它将在下一个版本中修复 0.11.8.0

感谢您抓住这个!



 类似资料:
  • 问题内容: 在无法实例化或扩展MyClass的地方如何使用clazz进行调用。 编辑:“ David Winslow”和“ bmargulies”响应是原始问题的正确作品,但令人惊讶的是,该方法返回说而不是强制类型转换时将不再编译。 编辑:我已经用MyClass替换列表,并将条件添加到我原来的问题。 问题答案: 使用。因为类型擦除类型参数的Java类是完全编译时结构- 即使是有效的语法,这将是 完

  • 问题内容: 如何通过MySQL和PHP 进行设置? 我的代码: 问题答案: 除了修复/ gotcha之外,还可以通过要求数据库在查询中每年仅返回一次来保存数组查找,并使代码更简单: (您可能不需要假设这是一个数字年份,但是始终将HTML模板中包含的任何纯文本都用HTML转义是一种很好的做法。您可以定义一个名称较短的函数来减少输入。)

  • 问题内容: 我需要找到当天创建的帐户,以及最近7天创建的帐户。 为了找到今天的结果,它可以正常工作,我可以这样做: 但是我不知道如何获得最近的7天帐户。 我尝试了类似的方法,但是没有成功: 你有主意吗? 问题答案: 在mysql中:

  • 本文向大家介绍你在做项目中有做过压力测试吗,怎么做相关面试题,主要包含被问及你在做项目中有做过压力测试吗,怎么做时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 1、首先对要测试的系统进行分析,明确需要对那一部分做压力测试,比如秒杀,支付 2、如何对这些测试点进行施压 第一种方式可以通过写脚本产生压力机器人对服务器进行发包收报操作 第二点借助一些压力测试工具比如Jmeter,LoadRunn

  • 问题内容: 我正在使用Datanucleus和JDO开发用于嵌入式H2数据库的桌面应用程序。当我从Eclipse运行它时,一切正常,但是当我尝试用它制作可执行jar时,它将停止工作。我收到以下错误: org.datanucleus.exceptions.NucleusUserException:已指定持久性进程使用名称为“ jdo”的ClassLoaderResolver,但DataNucleus

  • 问题内容: 我正在尝试模仿我在C#中使用NEST在Sense(chrome插件)中编写的查询。我不知道这两个查询之间的区别是什么。Sense查询返回记录,而nest查询则不。查询如下: 和 这两个查询有什么区别?为什么一个返回记录而另一个不返回? 问题答案: 您可以通过以下代码找出NEST使用的查询: 然后,您可以比较输出。