ES基础查知识汇总

有一种忘记,没有痛楚,它会随风飘逝,有若花开花落。当你回首,你才发现那么容易忘记的,是青春;有一种忘记,鲜活如昨,你使劲气力想要把他的身影刮落,百折千回,他仍然在记忆里;有一种忘记,会让你嘴角一咧微笑对自己说根本没爱过;有一种忘记却总让你一次次落泪

Posted by yishuifengxiao on 2022-02-25

image-20220224153345692


  • 叶子查询

  • 基于词项的查询

      term查询
      terms查询
      terms_set查询
      rangge查询
      exists查询
      模式匹配
          prefix查询
          wildcard查询
          regexp查询
      type查询
      ids查询
    
  • 基于全文的查询
      词项匹配
          match查询
          multi_match查询
      短语匹配
          match_phrase查询
          match_phrase_prefix查询
      查询字符串
          query_string查询
          simple_query_string查询
    

-组合查询
可以包含一个或多个子查询

参考资料:

官方文档地址 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-search.html

sql在线转es http://www.ischoolbar.com/EsParser/

API列表 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/rest-apis.html

一 基础API

1.1 索引

参见文档 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/indices.html

1.1.1 查询全部索引

1
get /_cat/indices

响应如下:

1
2
3
yellow open demo1   JrjxztgmQvO5CXyvFdTZwg 1 1  7712   1041  124.7mb  124.7mb
green open .kibana_1 zgRtGHQLSEC28Gq87Sanew 1 0 1 0 3.7kb 3.7kb
yellow open demo2 4KE9zKvnRbuYwIs7lqj6fw 1 1 8 0 61.4kb 61.4kb

1.1.2 创建索引

语法如下:

1
put /索引名字

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
PUT /tax_data_kettle
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"analysis": {
"filter": {
"word_sync": {
"type": "sync_ik"
}
},
"analyzer": {
"ik_sync_smart": {
"filter": [
"word_sync"
],
"type": "custom",
"tokenizer": "smart_ik"
}
}
}
},
"mappings": {
"properties": {
"attach_files": {
"properties": {
"file_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"analyzer": "ik_sync_smart"
},
"file_url": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"currentTimeMillis": {
"type": "long"
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"mainText": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"copy_to": [
"main_title"
],
"analyzer": "ik_sync_smart"
},
"main_title": {
"type": "text"
},
"publishTime": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"spiderTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"copy_to": [
"main_title"
],
"analyzer": "ik_sync_smart"
}
}
}
}

1.2 查询全部插件

1
get /_cat/plugins

响应如下:

1
node-1 ik-sync 0.0.1-SNAPSHOT

1.3 分词

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/indices-analyze.html

语法如下:

1
2
3
4
GET /_analyze
POST /_analyze
GET /<index>/_analyze
POST /<index>/_analyze

参数解释

  • <index>:(可选,字符串)用于派生分析器的索引。如果指定,分析器或 参数将覆盖此值。如果未指定分析器或字段,则分析 API 使用索引的默认分析器。如果未指定索引或索引没有默认分析器,则分析 API 使用 standard analyzer

默认分词

1
2
3
4
5
POST /_analyze
{
"analyzer": "分词器",
"text": "待分词的文本"
}

指定索引下的分词

1
2
3
4
5
POST /索引名/_analyze
{
"analyzer": "分词器",
"text": "待分词的文本"
}

二 文档API

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs.html

2.1 创建文档

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-index_.html

语法如下:

1
2
3
4
PUT /<index>/_doc/<_id>
POST /<index>/_doc/
PUT /<index>/_create/<_id>
POST /<index>/_create/<_id>

参数:

  • <index> : (必需,字符串)目标索引的名称。 默认情况下,如果索引不存在,则会自动创建该索引。
  • <_id> : (可选,字符串)文档的唯一标识符。 如果您使用 PUT 请求,则为必需。 使用 POST 请求时省略自动生成 ID。

请求体:

  • <field>:(必需,字符串)请求正文包含文档数据的 JSON 源。

2.1.1 自动创建ID

如果您在使用 POST 时不指定文档 ID,则会自动设置为,并且索引操作会为 document.op_type生成唯一 ID

示例

1
2
3
4
5
6
POST twitter/_doc/
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}

响应为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_shards" : {
"total" : 2,
"failed" : 0,
"successful" : 2
},
"_index" : "twitter",
"_type" : "_doc",
"_id" : "W0tpsmIBdwcYyG50zbta",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"result": "created"
}

2.1.2 超时

执行索引操作时,分配给执行索引操作的主分片可能不可用。 造成这种情况的一些原因可能是主分片当前正在从网关恢复或正在进行重定位。 默认情况下,索引操作将在主分片上等待最多 1 分钟,然后才会失败并以错误响应。 该参数可用于明确指定等待的时间。 这是将其设置为 5 分钟的示例:超时

1
2
3
4
5
6
PUT twitter/_doc/1?timeout=5m
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}

2.1.3 指定ID

将 JSON 文档插入_id 为 1 的 twitter 索引:

1
2
3
4
5
6
PUT twitter/_doc/1
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}

如果不存在具有该 ID 的文档,则使用_create 资源将文档索引到 twitter 索引中:

1
2
3
4
5
6
PUT twitter/_create/1
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}

如果不存在具有该 ID 的文档,则将 op_type 参数设置为 create 以将文档索引到 twitter 索引中:

1
2
3
4
5
6
PUT twitter/_doc/1?op_type=create
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}

2.2 GET查询文档

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html

语法如下:

1
2
3
4
GET <index>/_doc/<_id>
HEAD <index>/_doc/<_id>
GET <index>/_source/<_id>
HEAD <index>/_source/<_id>

参数:

  • <index>: (必需,字符串)包含文档的索引的名称。
  • <_id>:(必需,字符串)文档的唯一标识符。

从 twitter 索引中检索 _id 为 0 的 JSON 文档:

1
GET twitter/_doc/0

响应如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "0",
"_version" : 1,
"_seq_no" : 10,
"_primary_term" : 1,
"found": true,
"_source" : {
"user" : "kimchy",
"date" : "2009-11-15T14:12:12",
"likes": 0,
"message" : "trying out Elasticsearch"
}
}

使用 <index>/_source/<id> 资源仅获取文档的 _source字段。 例如:

1
GET twitter/_source/1

2. 3 删除文档

语法如下

1
DELETE /<index>/_doc/<_id>

参数:

  • <index>: (必需,字符串)目标索引的名称。
  • <_id>:(必需,字符串)文档的唯一标识符。

从 twitter 索引中删除 JSON 文档 1:

1
DELETE /twitter/_doc/1

响应如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_shards" : {
"total" : 2,
"failed" : 0,
"successful" : 2
},
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_primary_term": 1,
"_seq_no": 5,
"result": "deleted"
}

2.4 _delete_by_query

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-delete-by-query.html

语法如下:

1
POST /<index>/_delete_by_query

参数:

  • <index> : (可选,字符串)要搜索的索引名称的逗号分隔列表。 使用 _all 或省略搜索所有索引。

请求体:

  • query:(可选,查询对象)使用查询 DSL 指定要删除的文档。

从 twitter 索引中删除所有推文:

1
2
3
4
5
6
POST twitter/_delete_by_query?conflicts=proceed
{
"query": {
"match_all": {}
}
}

从多个索引中删除文档:

1
2
3
4
5
6
POST /twitter,blog/_delete_by_query
{
"query": {
"match_all": {}
}
}

默认情况下,_delete_by_query 使用 1000 个滚动批次。您可以使用 scroll_size URL 参数更改批次大小:

1
2
3
4
5
6
7
8
POST twitter/_delete_by_query?scroll_size=5000
{
"query": {
"term": {
"user": "kimchy"
}
}
}

2.5 更新文档

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-update.html

使您能够编写文档更新脚本。 该脚本可以更新、删除或跳过修改文档。 更新 API 还支持传递部分文档,该部分文档会合并到现有文档中。 要完全替换现有文档,请使用索引 API。

这个操作:

  1. 从索引中获取文档(与分片并置)。

  2. 运行指定的脚本。

  3. 索引结果。

该文档仍必须重新索引,但使用更新消除了一些网络往返并减少了 GET 和索引操作之间版本冲突的可能性。

必须启用 _source 字段才能使用更新。 除了_source,您还可以通过 ctx map 访问以下变量:_index_type_id_version_routing_now(当前时间戳)。

语法如下:

1
POST /<index>/_update/<_id>

参数:

  • <index>: (必需,字符串)包含文档的索引的名称。
  • <_id>:(必需,字符串)文档的唯一标识符。

示例

1
2
3
4
5
PUT test/_doc/1
{
"counter" : 1,
"tags" : ["red"]
}

三 基于词项的查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/term-level-queries.html

3.1 term查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-term-query.html

返回在提供的字段中包含exact term 的文档。

您可以使用术语查询根据价格、产品 ID 或用户名等精确值查找文档。

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

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

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

示例

1
2
3
4
5
6
7
8
9
10
11
GET /_search
{
"query": {
"term": {
"user": {
"value": "Kimchy",
"boost": 1.0
}
}
}
}

参数:

  • value : (必需,字符串)您希望在提供的 <field>中找到的术语。 要返回文档,术语必须与字段值完全匹配,包括空格和大写。
  • boost:(可选,浮点数)用于降低或提高查询相关性分数的浮点数。 默认为 1.0。您可以使用 boost 参数来调整包含两个或多个查询的搜索的相关性分数。提升值相对于默认值 1.0。 介于 0 和 1.0 之间的提升值会降低相关性分数。 大于 1.0 的值会增加相关性分数。

注意 : 避免使用term查询text类型的字段

默认情况下,Elasticsearch 在分析期间会更改text字段的值。 例如,默认标准分析器更改text字段值如下:

  1. 删除大部分标点符号
  2. 将剩余的内容分成单独的单词,称为标记
  3. 小写标记

为了更好地搜索文本字段,匹配查询还会在执行搜索之前分析您提供的搜索词。 这意味着匹配查询可以在text字段中搜索已分析的标记,而不是精确的term

term查询不分析搜索词条。 term查询仅搜索您提供的确切term。 这意味着在搜索text字段时,term查询可能会返回较差的结果或没有结果。

3.2 terms查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-terms-query.html

返回在提供的字段中包含一个或多个确切terms的文档。

terms 查询与term查询相同,但您可以搜索多个值。

示例

以下搜索返回用户字段包含 kimchy 或 elasticsearch 的文档。

1
2
3
4
5
6
7
8
9
GET /_search
{
"query" : {
"terms" : {
"user" : ["kimchy", "elasticsearch"],
"boost" : 1.0
}
}
}

参数 :

  • <field>:(可选,对象)您要搜索的字段。此参数的值是您希望在提供的字段中找到的术语数组。 要返回文档,一个或多个术语必须与字段值完全匹配,包括空格和大写。默认情况下,Elasticsearch 将术语查询限制为最多 65,536 个术语。 您可以使用 index.max_terms_count 设置更改此限制。
  • boost:(可选,浮点数)用于降低或提高查询相关性分数的浮点数。 默认为 1.0。您可以使用 boost 参数来调整包含两个或多个查询的搜索的相关性分数。提升值相对于默认值 1.0。 介于 0 和 1.0 之间的提升值会降低相关性分数。 大于 1.0 的值会增加相关性分数。

3.3 terms_set查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-terms-set-query.html

3.4 rangge查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-range-query.html

返回包含给定范围内terms 的文档。

以下搜索返回年龄字段包含 10 到 20 之间的术语的文档。

1
2
3
4
5
6
7
8
9
10
11
12
GET _search
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte" : 20,
"boost" : 2.0
}
}
}
}

3.5 wildcard查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-wildcard-query.html

返回包含与通配符模式匹配的术语的文档。

以下搜索返回用户字段包含以 ki 开头并以 y 结尾的术语的文档。 这些匹配项可以包括 kiy、kity 或 kimchy。

1
2
3
4
5
6
7
8
9
10
11
12
GET /_search
{
"query": {
"wildcard": {
"user": {
"value": "ki*y",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}

四 基于全文的查询

https://www.elastic.co/guide/en/elasticsearch/reference/7.3/full-text-queries.html

4.1 match查询

返回与提供的文本、数字、日期或布尔值匹配的文档。 在匹配之前分析提供的文本。

匹配查询是执行全文搜索的标准查询,包括模糊匹配选项。

https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-match-query.html

示例

1
2
3
4
5
6
7
8
9
10
GET /_search
{
"query": {
"match" : {
"message" : {
"query" : "this is a test"
}
}
}
}

参数为:

  • query :(Required) Text, number, boolean value or date you wish to find in the provided .<field> The query analyzes any provided text before performing a search. This means the query can search text fields for analyzed tokens rather than an exact term.match``match

  • analyzer:(Optional, string) Analyzer used to convert the text in the value into tokens. Defaults to the index-time analyzer mapped for the . If no analyzer is mapped, the index’s default analyzer is used. query``<field>

  • auto_generate_synonyms_phrase_query:(Optional, boolean) If , match phrase queries are automatically created for multi-term synonyms. Defaults to .true``true

  • See Use synonyms with match query for an example.

  • fuzziness:(Optional, string) Maximum edit distance allowed for matching. See Fuzziness for valid values and more information. See Fuzziness in the match query for an example.

  • max_expansions: (Optional, integer) Maximum number of terms to which the query will expand. Defaults to . 50

  • prefix_length:(Optional, integer) Number of beginning characters left unchanged for fuzzy matching. Defaults to . 0

  • fuzzy_transpositions:(Optional, boolean) If , edits for fuzzy matching include transpositions of two adjacent characters (ab → ba). Defaults to . true``true

  • fuzzy_rewrite:(Optional, string) Method used to rewrite the query. See the rewrite parameter for valid values and more information.

  • If the parameter is not , the query uses a method of by default.fuzziness``0``match``rewrite``top_terms_blended_freqs_${max_expansions}

  • lenient:(Optional, boolean) If , format-based errors, such as providing a text value for a numeric field, are ignored. Defaults to . true``query``false

  • operator:(Optional, string) Boolean logic used to interpret text in the value. Valid values are:query

  • OR (Default):For example, a value of is interpreted as . query``capital of Hungary``capital OR of OR Hungary

  • AND:For example, a value of is interpreted as . query``capital of Hungary``capital AND of AND Hungary

  • minimum_should_match:(Optional, string) Minimum number of clauses that must match for a document to be returned. See the minimum_should_match parameter for valid values and more information.

  • zero_terms_query:(Optional, string) Indicates whether no documents are returned if the removes all tokens, such as when using a filter. Valid values are:analyzer``stop

  • none (Default):No documents are returned if the removes all tokens. analyzer

  • all:Returns all documents, similar to a match_all query.

4.1.1 同义词

该查询支持使用 synonym_graph 标记过滤器进行多术语同义词扩展。 使用此过滤器时,解析器会为每个多词同义词创建一个短语查询。 例如,以下同义词:match”ny, new york” 会产生:

1
(ny OR ("new york"))

也可以用连词来匹配多词同义词:

1
2
3
4
5
6
7
8
9
10
11
GET /_search
{
"query": {
"match" : {
"message": {
"query" : "ny city",
"auto_generate_synonyms_phrase_query" : false
}
}
}
}

上面的示例创建了一个布尔查询:

1
(ny OR (new AND york)) city

匹配带有 term 或连词的文档。 默认情况下,参数设置为 .nynew AND yorkauto_generate_synonyms_phrase_querytrue

4.2 multi_match查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-multi-match-query.html

multi_match查询基于 match查询以允许多字段查询:

1
2
3
4
5
6
7
8
9
GET /_search
{
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "message" ]
}
}
}

可以使用通配符指定字段,例如:

1
2
3
4
5
6
7
8
9
GET /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"fields": [ "title", "*_name" ]
}
}
}

可以使用插入符号 (^) 符号来提升各个字段权重:

1
2
3
4
5
6
7
8
9
GET /_search
{
"query": {
"multi_match" : {
"query" : "this is a test",
"fields" : [ "subject^3", "message" ]
}
}
}

subject字段的重要性是message字段的三倍。

如果未提供任何字段,则 multi_match 查询默认为 index.query.default_field 索引设置,而后者又默认为 *.* 提取映射中符合术语查询条件的所有字段并过滤元数据字段。 然后组合所有提取的字段以构建查询。

一次可以查询的字段数量是有限制的。 它由 indices.query.bool.max_clause_count 搜索设置定义,默认为 1024。

4.2.1 查询参数设置

内部执行 multi_match 查询的方式取决于 type 参数,可以设置为:

best_fields (default) Finds documents which match any field, but uses the _score from the best field. See best_fields.
most_fields Finds documents which match any field and combines the _score from each field. See most_fields.
cross_fields Treats fields with the same analyzer as though they were one big field. Looks for each word in any field. See cross_fields.
phrase Runs a match_phrase query on each field and uses the _score from the best field. See phrase and phrase_prefix.
phrase_prefix Runs a match_phrase_prefix query on each field and uses the _score from the best field. See phrase and phrase_prefix.
bool_prefix Creates a match_bool_prefix query on each field and combines the _score from each field. See bool_prefix.

best_fields 类型在您搜索在同一字段中最好找到的多个单词时最有用。 例如,单个字段中的“brown fox”比一个字段中的“brown”和另一个字段中的“fox”更有意义。

best_fields 类型为每个字段生成一个匹配查询,并将它们包装在一个 dis_max 查询中,以找到单个最佳匹配字段。 例如,这个查询:

1
2
3
4
5
6
7
8
9
10
11
GET /_search
{
"query": {
"multi_match" : {
"query": "brown fox",
"type": "best_fields",
"fields": [ "subject", "message" ],
"tie_breaker": 0.3
}
}
}

它等价于

1
2
3
4
5
6
7
8
9
10
11
12
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "subject": "brown fox" }},
{ "match": { "message": "brown fox" }}
],
"tie_breaker": 0.3
}
}
}

通常 best_fields 类型使用单个最佳匹配字段的分数,但如果指定了 tie_breaker,那么它会按如下方式计算分数:

  • 最佳匹配字段的分数
  • 加上所有其他匹配字段的 tie_breaker * _score

4.2.2 operator和minimum_should_match

best_fieldsmost_fields 类型以字段为中心 — 它们为每个字段生成匹配查询。 这意味着 operatorminimum_should_match 参数分别应用于每个字段,这可能不是您想要的。

以这个查询为例:

1
2
3
4
5
6
7
8
9
10
11
GET /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "best_fields",
"fields": [ "first_name", "last_name" ],
"operator": "and"
}
}
}

查询等价于

1
2
 (+first_name:will +first_name:smith)
| (+last_name:will +last_name:smith)

4.2.3 phrase和phrase_prefix

短语和短语前缀类型的行为就像 best_fields,但它们使用 match_phrasematch_phrase_prefix 查询而不是 match 查询。

这个查询:

1
2
3
4
5
6
7
8
9
10
GET /_search
{
"query": {
"multi_match" : {
"query": "quick brown f",
"type": "phrase_prefix",
"fields": [ "subject", "message" ]
}
}
}

等价于

1
2
3
4
5
6
7
8
9
10
11
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "match_phrase_prefix": { "subject": "quick brown f" }},
{ "match_phrase_prefix": { "message": "quick brown f" }}
]
}
}
}

4.3 match_phrase查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-match-query-phrase.html

match_phrase 查询分析文本并根据分析的文本创建短语查询。 例如:

1
2
3
4
5
6
7
8
GET /_search
{
"query": {
"match_phrase" : {
"message" : "this is a test"
}
}
}

短语查询以任何顺序匹配术语到可配置的间隔(默认为 0)。

可以设置分析器来控制哪个分析器将对文本执行分析过程。 它默认为字段显式映射定义,或默认搜索分析器,例如:

1
2
3
4
5
6
7
8
9
10
11
GET /_search
{
"query": {
"match_phrase" : {
"message" : {
"query" : "this is a test",
"analyzer" : "my_analyzer"
}
}
}
}

4.4 match_phrase_prefix查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-match-query-phrase-prefix.html

以与提供的相同顺序返回包含所提供文本的单词的文档。 所提供文本的最后一个词被视为前缀,匹配以该词开头的任何单词。

以下搜索将返回消息字段中包含以 quick brown f 开头的短语的文档。

This search would match a message value of quick brown fox or two quick brown ferrets but not the fox is quick and brown.

1
2
3
4
5
6
7
8
9
10
GET /_search
{
"query": {
"match_phrase_prefix" : {
"message" : {
"query" : "quick brown f"
}
}
}
}

五组合查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/compound-queries.html

5.1 Boolean query

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-bool-query.html

匹配与其他查询的布尔组合匹配的文档的查询。 bool 查询映射到 Lucene 。 它是使用一个或多个布尔子句构建的,每个子句都有一个类型的出现。 出现类型为:BooleanQuery

条件 说明
filter 只过滤符合条件的文档,不计算相关性得分
must 文档必须符合 must 中所有的条件,会影响相关性得分
must_not 文档必须不符合 must 中所有的条件
should 文档可以符合 should 中的条件,会影响相关性得分

bool 查询采用more-matches-is-better 方法,因此每个匹配的mustshould 子句的分数将被加在一起以提供每个文档的最终_score

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
}
}
}

5.1.1 Scoring with bool.filter

在过滤器元素下指定的查询对评分没有影响 — 分数返回为 0。分数仅受已指定的查询影响。 例如,以下所有三个查询都返回状态字段包含术语活动的所有文档。

第一个查询为所有文档分配 0 分,因为没有指定评分查询:

1
2
3
4
5
6
7
8
9
10
11
12
GET _search
{
"query": {
"bool": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}

这个 bool 查询有一个 match_all 查询,它为所有文档分配 1.0 的分数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET _search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"status": "active"
}
}
}
}
}

5.1.2 常见示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"match_phrase": {
"name": {
"query": "AAAA"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"wildcard": {
"nickname": "*BBB*"
}
}
]
}
},
{
"range": {
"age": {
"gt": "10"
}
}
},
{
"range": {
"year": {
"gt": "1000",
"lt": "2000"
}
}
}
]
}
}
}

上面的查询条件等价于

1
from user where name="AAAA" and nickname like "%BBB%" and age>10 and year >1000 and year <2000

示例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
{
"size": 100,
"query": {
"bool": {
"filter": [
{
"range": {
"year": {
"lte": 2010,
"gte": 2006
}
}
},
{
"term": {
"prefer.keyword": "true"
}
},
{
"term": {
"dataType.keyword": "POLICY"
}
},
{
"term": {
"taxTypes.keyword": "增值税"
}
},
{
"term": {
"statuName.keyword": "全文有效"
}
}
],
"must": [
{
"multi_match": {
"minimum_should_match": 1,
"fields": [
"title^400",
"title.keyword^500",
"docNo^400",
"docNo.keyword^500",
"dataType.keyword",
"mainText"
],
"type": "most_fields",
"query": "增值税"
}
}
]
}
},
"_source": {
"excludes": [
"alian",
"extractHtml",
"html"
]
},
"from": 0,
"sort": [
{
"_score": "desc"
}
]
}

5.2 Disjunction max query

返回匹配一个或多个包装查询的文档,称为查询子句或子句。

如果返回的文档与多个查询子句匹配,则 dis_max 查询为该文档分配来自任何匹配子句的最高相关性分数,并为任何其他匹配的子查询加上一个平局增量。

您可以使用 dis_max 在映射有不同提升因子的字段中搜索术语。

1
2
3
4
5
6
7
8
9
10
11
12
GET /_search
{
"query": {
"dis_max" : {
"queries" : [
{ "term" : { "title" : "Quick pets" }},
{ "term" : { "body" : "Quick pets" }}
],
"tie_breaker" : 0.7
}
}
}

参数

  • queries:(必需,查询对象数组)包含一个或多个查询子句。 返回的文档必须与这些查询中的一个或多个匹配。 如果一个文档匹配多个查询,Elasticsearch 使用最高的相关性分数。
  • tie_breaker:可选,float)0到1.0之间的浮点数,用于增加匹配多个查询子句的文档的相关性分数。 默认为 0.0。

您可以使用 tie_breaker 值将更高的相关性分数分配给在多个字段中包含相同术语的文档,而不是仅在这些多个字段中的最佳字段中包含该术语的文档,而不会将这与多个字段中两个不同术语的更好情况混淆 字段。

如果文档匹配多个子句,则 dis_max 查询计算文档的相关性分数,如下所示:

  • 从得分最高的匹配子句中获取相关性得分。
  • 将任何其他匹配子句的分数乘以 tie_breaker 值。
  • 将最高分数添加到相乘分数中。

如果 tie_breaker 值大于 0.0,则所有匹配的子句都计数,但得分最高的子句计数最多。

5.3 多条件查询

5.3.1 and和or混合查询

1
select * from table where taxs.keyword='增值税' and ( docNo ='2012 36' or docNo.keyword= '2012 36' )

上面的查询语句大致等价于(类似于)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"query": {
"bool": {
"filter": [
{
"term": {
"taxs.keyword": "增值税"
}
}
],
"must": [
{
"bool": {
"should": [
{
"multi_match": {
"minimum_should_match": 2,
"fields": [
"title^400",
"title.keyword^500",
"docNo^400",
"docNo.keyword^500",
"mainText"
],
"type": "most_fields",
"query": "2012 36"
}
},
{
"wildcard": {
"docNo.keyword": {
"value": "*2012*36*"
}
}
}
]
}
}
]
}
}
}

六 聚合查询

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket.html

桶聚合不像度量聚合那样计算字段的度量,而是创建文档桶。 每个存储桶都与一个标准(取决于聚合类型)相关联,该标准确定当前上下文中的文档是否“落入”其中。 换句话说,桶有效地定义了文档集。 除了存储桶本身之外,聚合还计算并返回“落入”每个存储桶的文档数量。bucket

与聚合相反,桶聚合可以保存子聚合。 这些子聚合将为其“父”存储桶聚合创建的存储桶聚合。

有不同的桶聚合器,每个都有不同的“桶”策略。 一些定义单个桶,一些定义固定数量的多个桶,还有一些在聚合过程中动态创建桶。

单个响应中允许的最大桶数受名为 的动态集群设置的限制。 它默认为 10,000,尝试返回超过限制的请求将失败并出现 exception.search.max_buckets

6.1 邻接矩阵的桶聚合

返回一种形式的邻接矩阵的桶聚合。 该请求提供了一组命名过滤器表达式,类似于过滤器聚合请求。 响应中的每个桶代表相交过滤器矩阵中的一个非空单元格。

给定名为 A、B 和 C 的过滤器,响应将返回具有以下名称的存储桶:

A B C
A A A&B A&C
B B B&C
C C

相交的桶,例如 A&C 使用由 & 字符分隔的两个过滤器名称的组合来标记。 请注意,响应也不包括“C&A”存储桶,因为这将是与“A&C”相同的文档集。 据说矩阵是对称的,所以我们只返回它的一半。 为此,我们对过滤器名称字符串进行排序,并始终使用一对中的最低值作为“&”分隔符左侧的值。

如果客户端希望使用与默认值不同的分隔符字符串,则可以在请求中传递替代分隔符参数。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PUT /emails/_bulk?refresh
{ "index" : { "_id" : 1 } }
{ "accounts" : ["hillary", "sidney"]}
{ "index" : { "_id" : 2 } }
{ "accounts" : ["hillary", "donald"]}
{ "index" : { "_id" : 3 } }
{ "accounts" : ["vladimir", "donald"]}

GET emails/_search
{
"size": 0,
"aggs" : {
"interactions" : {
"adjacency_matrix" : {
"filters" : {
"grpA" : { "terms" : { "accounts" : ["hillary", "sidney"] }},
"grpB" : { "terms" : { "accounts" : ["donald", "mitt"] }},
"grpC" : { "terms" : { "accounts" : ["vladimir", "nigel"] }}
}
}
}
}
}

在上面的示例中,我们分析电子邮件消息以查看哪些个人组交换了消息。 我们将分别获得每个组的计数,以及记录交互的成对组的消息计数。

响应如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"took": 9,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"interactions": {
"buckets": [
{
"key":"grpA",
"doc_count": 2
},
{
"key":"grpA&grpB",
"doc_count": 1
},
{
"key":"grpB",
"doc_count": 2
},
{
"key":"grpB&grpC",
"doc_count": 1
},
{
"key":"grpC",
"doc_count": 1
}
]
}
}
}

这种聚合本身可以提供创建无向加权图所需的所有数据。 但是,当与诸如 date_histogram 之类的子聚合一起使用时,结果可以提供执行动态网络分析所需的额外数据级别,其中检查随时间变化的交互变得很重要。

6.2 自动间隔日期直方图聚合

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket-autodatehistogram-aggregation.html

类似于日期直方图聚合的多桶聚合,除了不提供用作每个桶的宽度的间隔,而是提供桶的目标数量,指示所需的桶数,并且桶的间隔自动选择为最佳 实现该目标。 返回的桶数将始终小于或等于此目标数。

buckets 字段是可选的,如果未指定,则默认为 10 个桶。

请求 10 个存储桶的目标。

1
2
3
4
5
6
7
8
9
10
11
POST /sales/_search?size=0
{
"aggs" : {
"sales_over_time" : {
"auto_date_histogram" : {
"field" : "date",
"buckets" : 10
}
}
}
}

在内部,日期表示为一个 64 位数字,表示自时代以来的时间戳,以毫秒为单位。 这些时间戳作为存储桶键返回。 key_as_string 是使用 format参数指定的格式转换为格式化日期字符串的同一时间戳:

如果未指定格式,则它将使用字段映射中指定的第一个日期格式。

1
2
3
4
5
6
7
8
9
10
11
12
POST /sales/_search?size=0
{
"aggs" : {
"sales_over_time" : {
"auto_date_histogram" : {
"field" : "date",
"buckets" : 5,
"format" : "yyyy-MM-dd"
}
}
}
}

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
...
"aggregations": {
"sales_over_time": {
"buckets": [
{
"key_as_string": "2015-01-01",
"key": 1420070400000,
"doc_count": 3
},
{
"key_as_string": "2015-02-01",
"key": 1422748800000,
"doc_count": 2
},
{
"key_as_string": "2015-03-01",
"key": 1425168000000,
"doc_count": 2
}
],
"interval": "1M"
}
}
}

6.3 日期直方图聚合

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket-datehistogram-aggregation.html

这种多桶聚合类似于普通的直方图,但它只能与日期值一起使用。 因为日期在 Elasticsearch 内部表示为长值,所以也可以在日期上使用正常的直方图,但不准确。 这两个 API 的主要区别在于,此处可以使用日期/时间表达式指定时间间隔。 基于时间的数据需要特殊支持,因为基于时间的间隔并不总是固定长度。

配置日期直方图聚合时,可以通过两种方式指定时间间隔:日历感知时间间隔和固定时间间隔。

日历感知间隔了解夏令时会改变特定天数的长度,月份有不同的天数,并且闰秒可以附加到特定的年份。

相比之下,固定间隔始终是 SI 单位的倍数,并且不会根据日历上下文而改变。

例如,以下是一个聚合,请求日历时间中一个月的存储桶间隔:

1
2
3
4
5
6
7
8
9
10
11
POST /sales/_search?size=0
{
"aggs" : {
"sales_over_time" : {
"date_histogram" : {
"field" : "date",
"calendar_interval" : "month"
}
}
}
}

如果我们尝试重新创建之前的“月”calendar_interval,我们可以用 30 个固定天数来近似:

1
2
3
4
5
6
7
8
9
10
11
POST /sales/_search?size=0
{
"aggs" : {
"sales_over_time" : {
"date_histogram" : {
"field" : "date",
"fixed_interval" : "30d"
}
}
}
}

6.4 日期范围聚合

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket-daterange-aggregation.html

专用于日期值的范围聚合。 此聚合与正常范围聚合的主要区别在于 from 和 to 值可以用日期数学表达式表示,还可以指定返回 from 和 to 响应字段的日期格式。 请注意,此聚合包括 from 值并排除每个范围的 to 值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"format": "MM-yyyy",
"ranges": [
{ "to": "now-10M/M" },
{ "from": "now-10M/M" }
]
}
}
}
}

在上面的示例中,我们创建了两个范围存储桶,第一个将“存储”所有日期为 10 个月前的文档,第二个将“存储”所有日期为 10 个月前的文档

6.5 范围聚合

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket-range-aggregation.html

一种基于多桶值源的聚合,使用户能够定义一组范围——每个范围代表一个桶。 在聚合过程中,从每个文档中提取的值将根据每个桶范围检查并“桶”相关/匹配的文档。 请注意,此聚合包括 from 值并排除每个范围的 to 值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET /_search
{
"aggs" : {
"price_ranges" : {
"range" : {
"field" : "price",
"ranges" : [
{ "to" : 100.0 },
{ "from" : 100.0, "to" : 200.0 },
{ "from" : 200.0 }
]
}
}
}
}

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
...
"aggregations": {
"price_ranges" : {
"buckets": [
{
"key": "*-100.0",
"to": 100.0,
"doc_count": 2
},
{
"key": "100.0-200.0",
"from": 100.0,
"to": 200.0,
"doc_count": 2
},
{
"key": "200.0-*",
"from": 200.0,
"doc_count": 3
}
]
}
}
}

6.6 稀有词聚合

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket-rare-terms-aggregation.html

一种基于多桶值源的聚合,可找到“稀有”术语 — 位于分布长尾且不频繁的术语。 从概念上讲,这就像一个按 _count 升序排序的术语聚合。 如术语聚合文档中所述,实际上按计数升序对术语 agg 进行排序具有无限错误。 相反,您应该使用rare_terms 聚合

1
2
3
4
5
6
7
8
9
10
GET /_search
{
"aggs" : {
"genres" : {
"rare_terms" : {
"field" : "genre"
}
}
}
}

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
{
...
"aggregations" : {
"genres" : {
"buckets" : [
{
"key" : "swing",
"doc_count" : 1
}
]
}
}
}

6.7 术语聚合

参见 https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations-bucket-terms-aggregation.html

一种基于多桶值源的聚合,其中桶是动态构建的——每个唯一值一个。

1
2
3
4
5
6
7
8
GET /_search
{
"aggs" : {
"genres" : {
"terms" : { "field" : "genre" }
}
}
}

术语聚合应该是关键字类型的字段或任何其他适用于桶聚合的数据类型。 为了将它与文本一起使用,您需要启用 fielddata。

响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
...
"aggregations" : {
"genres" : {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets" : [
{
"key" : "electronic",
"doc_count" : 6
},
{
"key" : "rock",
"doc_count" : 3
},
{
"key" : "jazz",
"doc_count" : 2
}
]
}
}
}

6.8 筛选后聚合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"size": 0,
"query": {
"bool": {
"filter": [],
"must": [
{
"multi_match": {
"minimum_should_match": 2,
"fields": [
"title^400",
"title.keyword^500",
"docNo^400",
"docNo.keyword^500",
"dataType.keyword",
"mainText"
],
"type": "most_fields",
"query": "查询条件"
}
}
]
}
},
"aggs": {
"group_by_estate": {
"terms": {
"field": "estates.keyword",
"size": 100
}
},
"group_by_tax": {
"terms": {
"field": "taxTypes.keyword",
"size": 100
}
},
"group_by_stat": {
"terms": {
"field": "statuName.keyword"
}
},
"group_by_object": {
"terms": {
"field": "objects.keyword",
"size": 100
}
},
"group_by_type": {
"terms": {
"field": "types.keyword"
}
}
}
}

这里的100可以根据实际值设置,若使用默认值则最多聚合出来10项。