【问题标题】:How to write a composite Elasticsearch query including query_string for multiple fields?如何编写包含多个字段的 query_string 的复合 Elasticsearch 查询?
【发布时间】:2021-03-01 16:32:03
【问题描述】:

我的对象看起来像这样

{
      "country_id":3,
      "user_id":22,
      "name": "John",
      "surname": "Wright",
      "city_name":"Sydney",
}

我想这样做:

SELECT * FROM STUDENT WHERE user_id= :1 AND country_id= :2 
AND LOWER(name) LIKE '%' || :3 || '%' 
OR LOWER(surname) LIKE '%' || :4 || '%' 
OR LOWER(city_name) LIKE '%' || :5 || '%' 
OFFSET :6 ROWS FETCH NEXT :7 ROWS ONLY

我尝试了以下方法:

curl -XPOST "http://xxx.xxx.xxx.x:9200/xxxx/students/_search" -d '{
  "from": 6, "size": 11,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "country_id": "123"
          },
          {
          "term": {
            "user_id": "abc35"
          }
        },
        {
          "query_string": {
            "query": "name:*abc*",
            "query": "surname:*abc*",
            "query": "city_name:*abc*",
          }
        }
      ]
    }
  }
}

用户的搜索字符串将应用于名称、姓氏、城市名称等字段。

有人可以指出我缺少什么吗?我想要尽可能小的查询,因为可以在查询字符串中传递多个字段,以便应用用户的搜索查询(如学校名称、爱好、教育)。

【问题讨论】:

  • 另外值得注意的是,运行前缀通配符查询效率不高,并且可能会根据您拥有的数据量影响集群的性能。您应该看看使用 wildcard field type 是否对您的用例更有利。
  • @noobie 我添加了通配符样式查询和其他方法的一些链接。让elasticsearch大放异彩,尽量避免like%风格的查询。欢呼

标签: elasticsearch elastic-stack


【解决方案1】:

提取数据

POST test_noobie/_doc
{
  "country_id": 3,
  "user_id": 22,
  "name": "John",
  "surname": "Wright",
  "city_name": "Sydney"
}

查询

POST test_noobie/_search
{
  "query": {
    "bool": {
      "must": {
        "query_string": {
          "query": "*ydn*",
          "fields": [
            "city_name",
            "name",
            "surname"
          ]
        }
      },
      "filter": [
        {
          "term": {
            "user_id": 22
          }
        },
        {
          "term": {
            "country_id": 3
          }
        }
      ]
    }
  }
}

请注意,我将与 id 相关的过滤器放在过滤器范围内。这更有效,因为我们不关心精确匹配的评分,所以它被省略了。

回应

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_noobie",
        "_type" : "_doc",
        "_id" : "Tsck7HcB50NMsuQPC1TV",
        "_score" : 1.0,
        "_source" : {
          "country_id" : 3,
          "user_id" : 22,
          "name" : "John",
          "surname" : "Wright",
          "city_name" : "Sydney"
        }
      }
    ]
  }
}

顺便说一句,通配符很贵,使用它并不是最佳选择。你可以阅读更多关于其他策略的信息,我会附上一些链接:

转向全文搜索引擎的一大优势是在开始使用通配符、正则表达式或无痛脚本之前尽可能多地使用内置函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 2020-02-26
    相关资源
    最近更新 更多