Elasticsearch Query DSL 语言介绍

0. 引言

Elasticsearch 提供了强大的查询语言 Query DSL(Domian Specific Language)。Query DSL 是基于 JSON 数据格式来描述查询条件。本文的主要介绍如何使用 Query DSL ,包括语法规则和字段使用,同时配有相应例子供大家参考。

Elasticsearch 查询规则分为两类:Query context (查询上下文) 和 Filter context (过滤上下文)。他们对查询结果有不同的影响。Query 影响查询结果的相关性评分。Elasticsearch 会计算每条查询结果的相关性评分(relevance score),并按评分对结果进行排序。Filter 要求结果完全匹配 filter context 设置的查询条件,不会影响相关性评分。我们可以通过下面例子初步认识 Elasticsearch 查询语音。该查询语句会匹配满足全部以下条件的文档:

  • title 字段包含单词 search
  • content 字段包含单词 elasticsearch
  • status 字段为 published
  • publish_date 字段大于 2015 年 1 月
GET /_search
{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "title":   "Search"        }},
        { "match": { "content": "Elasticsearch" }}
      ],
      "filter": [ 
        { "term":  { "status": "published" }},
        { "range": { "publish_date": { "gte": "2015-01-01" }}}
      ]
    }
  }
}

命中一条结果:

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.5753642,
        "hits": [
            {
                "_index": "twitter",
                "_type": "1",
                "_id": "NpI0tGwBw88r7mqtr8EN",
                "_score": 0.5753642,
                "_source": {
                    "title": "My Search",
                    "content": "trying out Elasticsearch",
                    "status": "published",
                    "publish_date": "2019-11-15T14:12:12"
                }
            }
        ]
    }
}

接下来,我们就几种常见的查询场景依次介绍。

1. 组合查询

组合查询(Compound Queries)中的 bool query 用于在多个字段上进行组合查询,是一个查询中包含多个查询条件的查询。组合查询接受四种布尔匹配

  • must:必须匹配
  • filter:必须匹配(但对评分没有影响)
  • should:如果匹配,将增加相关性评分
  • must_not:必须不匹配(对评分贡献为0)

每一个子查询都独自地计算文档的相关性得分。每个文档的最终得分 _score 是各个分数的总合。以下是一个典型例子:

POST _search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "user" : "kimchy" }
      },
      "filter": {
        "term" : { "tag" : "tech" }
      },
      "must_not" : {
        "range" : {
          "age" : { "gte" : 10, "lte" : 20 }
        }
      },
      "should" : [
        { "term" : { "tag" : "wow" } },
        { "term" : { "tag" : "elasticsearch" } }
      ],
      "minimum_should_match" : 1,
      "boost" : 1.0
    }
  }
}

注:minimum_should_match 表示至少要满足的 should 语句。例子中有两条 should 语句,要求至少满足一条。

2. 全文搜索

2.1 Match

匹配查询(match query)也是布尔类型的查询。匹配查询会构造一个布尔查询来分析文本。布尔语句之间关系由 operator 字段定义,可选值为 or 和 and,默认是 or。如果是 or 的话,可以使用 minimum_should_match 来设置至少要匹配的 should 语句数量(默认为 1,至少一条)。

以下是一个典型例子。"this is a test" 是查询字符串。match 查询首先将查询字符串解析成一个词项列表,单词之间以非数字字母字符隔开。然后对这些词项进行搜索。筛选出 message 文本中包含`this、is 、a 或 test 至少一个单词的文档。

GET /_search
{
    "query": {
        "match" : {
            "message" : "this is a test"
        }
    }
}

等价于

GET /_search
{
   "query": {
       "bool" : {
           "should": [
               { "term": { "message": "this" }},
               { "term": { "message": "is" }},
               { "term": { "message": "a" }},
               { "term": { "message": "test" }},
           ]
       }
   }
}

2.2 Match Phase

短语匹配(match_phrase query)与匹配查询(match query)类似。但查询结果只保留那些包含全部搜索词项,且位置与搜索词项相同的文档。下面例子仅匹配 title 文本中包含 quick brown fox 短语的文档,且顺序不可变,中间不能夹带其他单词。

什么是短语?

一个被认定为和短语 quick brown fox 匹配的文档,必须满足以下这些要求:

  • quick 、 brown 和 fox 需要全部出现在域中。
  • brown 的位置应该比 quick 的位置大 1 。
  • fox 的位置应该比 quick 的位置大 2 。

如果以上任何一个选项不成立,则该文档不能认定为匹配。

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": "quick brown fox"
        }
    }
}

2.3 Multi Match

多字段匹配(multi_match query)是基于 match query 之上,允许同一查询作用在多个字段上。以下例子, match query 同时作用在字段 title 和 以 _name 结尾的字段,比如 first_name 和 last_name。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "Will Smith",
      "fields": [ "title", "*_name" ] 
    }
  }
}

2.4 Query String

查询字符串(query string)支持使用查询字符串语言(Query string syntax)来设置查询条件。

以下例子使用了查询字符串语言,表达式为 (new york city) OR (big apple)。相当于执行两条 match query,查询字符串分别是 new york city 和 big apple。如果要完整匹配短语的话,可以使用引号限定,比如 (new york city) OR ("big apple") 。

GET /_search
{
    "query": {
        "query_string" : {
            "query" : "(new york city) OR (big apple)",
            "default_field" : "content"
        }
    }
}

2.5 Simple Query String

Query String 如果表达式不合法会返回错误。在实际使用中,一般建议使用 Simple Query String。

3. 词项查询

词项查询(term-level queries)基于词项的查询如 term 或 fuzzy 查询不需要分析阶段,它们对单个词项进行操作。查用的词项查询类型有:

3.1 Range query

返回字段在指定范围内的文本

GET _search
{
    "query": {
        "range" : {
            "age" : {
                "gte" : 10,
                "lte" : 20,
                "boost" : 2.0
            }
        }
    }
}

3.2 Term query

返回字段完全匹配指定词项的文档。对于 text 类型的字段查询,建议使用 match query

GET /_search
{
    "query": {
        "term": {
            "user": {
                "value": "Kimchy",
                "boost": 1.0
            }
        }
    }
}

原文地址:https://www.cnblogs.com/huanggze/p/11395070.html