如何在 Elasticsearch 中编写“或”查询?

Posted

技术标签:

【中文标题】如何在 Elasticsearch 中编写“或”查询?【英文标题】:How can I write an "or" query in Elasticsearch? 【发布时间】:2021-09-17 00:24:42 【问题描述】:

我有这个 SQL:

select *
from users
where company_id = null
  or company_id = 123

如何在 Elasticsearch 中编写类似的查询?我希望查询返回所有具有company_idnil 或具有与当前用户匹配的company_id 的候选人。

我已经用 should 尝试过这个:

query: 
  bool: 
    should: [
      
        bool: 
          must_not: 
            exists: 
              field: "company_id"
            
          
        
      ,
      
        term: 
          company_id: 123
        
      
    ]
  

这将返回company_idnil 的用户。

我也尝试过使用正则表达式,但它会返回拥有company_id 的用户。

query: 
  bool: 
    should: [
      
        regexp: 
          comapny_id: ".+"
        
      ,
      
        term: 
          company_id: 
            value: 123
          
        
      
    ]
  

谢谢。

【问题讨论】:

第一次尝试哪种情况失败? 第二个,该查询只返回company_is为nil的用户 这SO Post 有帮助吗?我对弹性搜索语法不太熟悉 您的第一次尝试应该会奏效。 company_id 字段的数据类型是什么?当您只使用 term 查询时,您是否能够找到 ID 为 123 的候选人? company_id 在 elasticsearch 中的数据类型是 TEXT,因为在活动记录中它的数据类型是 UUID。不,当我只使用不返回候选人的术语时,我认为我的问题是这个术语查询。 【参考方案1】:

在您提到的 cmets 中,company_id 实际上是一个 UUID,当前类型为 text。您应该尝试将您的 company_id 更改为 keyword 字段。进行此更改后,您需要重新索引。

Elasticsearch 不建议对 text 字段使用 term 查询:

避免对text 字段使用term 查询。

默认情况下,Elasticsearch 会在分析过程中更改 text 字段的值。这会使查找 text 字段值的完全匹配变得困难。

要搜索text 字段值,请改用match 查询。

Term Query

他们的建议是使用match,但我认为您不需要支持对随机生成的 UUID 值的部分匹配,所以我认为您应该将您的字段定义为keyword

【讨论】:

非常感谢您,仅当我将 company_id 类型从文本更改为关键字时。 我可以用第一个查询运行必须,我想同时满足条件和运算符 是的,如果您要检查company_id 是否存在,您需要将must_not 更改为must。如果您说要要求两个过滤器都为 true,则需要将 should 更改为 must

以上是关于如何在 Elasticsearch 中编写“或”查询?的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch如何在 Elasticsearch 中轻松编写脚本

Elasticsearch如何在 Elasticsearch 中轻松编写脚本

Elasticsearch:如何在 Elasticsearch 中轻松编写 Painless 脚本

操作ElasticSearch(增删改查)

ElasticSearch海量数据使用简述

四十一 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作增删改查