Elasticsearch Query DSL 语言介绍

2023-06-15,,

目录

0. 引言
1. 组合查询
2. 全文搜索
2.1 Match
2.2 Match Phase
2.3 Multi Match
2.4 Query String
2.5 Simple Query String
3. 词项查询
3.1 Range query
3.2 Term query

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
            }
        }
    }
}

Elasticsearch Query DSL 语言介绍的相关教程结束。

《Elasticsearch Query DSL 语言介绍.doc》

下载本文的Word格式文档,以方便收藏与打印。