ES查询DSL之全文查询

全文搜索

间隔查询(intervals)

7.X的新特性,查询给定词组匹配指定间隔内的文档,例如:太极藿香,将分成 “太极” 和 “藿香”。可以设置两个词之间最多可有多大间隔才能匹配。若间隔设置为2,则“太极藿香正气液”间隔为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
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"query": {
"intervals" : {
"name" : {
"all_of" : {
"ordered" : true,
"intervals" : [
{
"match" : {
"query" : "太极藿香",
"max_gaps" : 1,
"ordered" : true
}
},
{
"any_of": {
"intervals": [
{
"match": {
"query": "口服液",
"max_gaps":-1
}
},
{
"match": {
"query": "匹配任一个",
"max_gaps":-1
}
}
]
}
}
]
}
}
}
}
}

  • 顶级参数 intervals

    1
    2
    3
    "intervals":{
    "field":{规则}
    }

    field: 必填,要搜索的字段名
    值是一个规则字段,字段可选规则如下:

规则
match
prefix
wildcard
all_of
any_of
filter
  • match规则参数

    按match规则匹配分析文档

参数 说明 是否必须
query 查询的关键字
max_gaps 匹配项之间的最大位置数,默认-1(不限),若为0则两个词必须相邻
ordered 如果为true,则匹配词必须以指定顺序出现,默认为false
analyzer 分词器,不指定默认为field的分词器
filter 间隔过滤器(https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-intervals-query.html#interval_filter
use_field 使用该字段中的搜索分析器分析术语。而不是使用顶级参数中指定的字段(field参数)这使您可以跨多个字段搜索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"query": {
"intervals" : {
"name" : {
"match" : {
"query" : "太极藿香",
"ordered": true,
"max_gaps":1,
"use_field":"productGeneralName"
}
}
}
}
}
  • prefix 规则参数

    该prefix规则匹配以指定字符集开头的文档,该前缀可以扩展以匹配最多128个词(terms),超过128个返回错误也可以使用index-prefixes限制、

参数 类型 说明 是否必须
prefix string 需要查询的前缀
analyzer string 分词器,默认field的分词器
use_field string 搜索该字段,而不是顶级参数中指定的field
  • wildcard 规则参数

    使用通配符模式匹配文档,最多可匹配128个词(terms),如果超出则返回错误

参数 类型 说明 是否必须
pattern string 通配符文本(正则)
analyzer string 分词器,默认顶级参数field的分词器
use_field string 匹配该字段,而不是顶级参数中指定的field
1
2
3
4
5
6
7
8
9
10
11
12
{
"query": {
"intervals" : {
"name" : {
"wildcard" : {
"pattern" : "龙胆?*",
"use_field":"productGeneralName"
}
}
}
}
}
  • all_of规则参数

    多用于嵌套查询,返回同时匹配多个组合规则的文档

参数 类型 说明 是否必须
intervals 对象数组 要组合的规则数组,所有规则都必须匹配才会返回
max_gaps 整数 匹配项之间的最大位置数, 否,默认-1
ordered 布尔值 是否按规则指定顺序出现 否,默认false
filter 间隔过滤器对象 间隔过滤器
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
{
"query": {
"intervals" : {
"name" : {
"all_of":
{
"max_gaps":2,
"ordered":true,
"intervals":[
{
"match" : {
"query" : "复方龙胆",
"use_field":"productGeneralName"
}
},
{
"match" : {
"query" : "氢钠碳酸",
"max_gaps":1,
"ordered":false,
"use_field":"productGeneralName"
}
}
]
}
}
}
}
}
  • any_of规则参数

    返回匹配规则组中任何一组规则的文档

参数 类型 说明 是否必须
intervals 规则对象数组 要组合的规则数组,匹配任一项即可
filter 间隔过滤器对象 间隔过滤器
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
{
"query": {
"intervals" : {
"name" : {
"any_of":
{
"intervals":[
{
"match" : {
"query" : "复方龙胆片",
"ordered":true,
"max_gaps":0
}
},
{
"match" : {
"query" : "太极藿香正气",
"max_gaps":1,
"ordered":false,
"use_field":"productGeneralName"
}
}
]
}
}
}
}
}

匹配查询(match)

ES的标准查询,用于匹配搜索的文字,模糊查询

1
2
3
4
5
6
7
8
9
10
GET /_search
{
"query": {
"match" : {
"productName" : {
"query" : "阿莫西林"
}
}
}
}

首先以query开头,查询方式为match,字段为productName
然后设置字段查询相关属性:

  • query(必填)

    查询的内容。

  • analyzer(可选,字符串)

    分词器,输入的keywords分词,若不设置则使用索引的分词器

  • auto_generate_synonyms_phrase_query(可选,布尔值,默认为true)

    是否开启近义词组合查询

  • fuzziness(可选,字符串)

    模糊性,解决一些拼写错误的场景,word 被写成world,那么要把world转换成word只需要将l删除,那么就是一次编辑,距离就是1,经过几次编辑距离就是几。该参数用于设置匹配允许的最大编辑距离,参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#fuzziness

  • max_expansions(可选,整数,默认50)

    terms查询能扩展的最大数

  • prefix_length(可选,整数,默认0)

    为模糊匹配保留的起始字符数,配合fuzziness使用的,保留前几个字符精确匹配,后面的模糊

  • transpositions(可选,布尔值,默认true)

    模糊匹配的编辑内容包括两个相邻字符的转置(ab→ba),如wodr转为word只需要转换一次,即为一次编辑,配合fuzziness使用

  • fuzzy_rewrite(可选,字符串)

    用于重写查询的方法,配合fuzziness使用

  • lenient(可选,布尔值,默认false)

    是否忽略格式错误,例如:数字字段输入字符串

  • operator(可选,字符串,默认OR)

    值为OR或AND,比如搜索:i like you 会解析成:i OR like OR you,就是搜索词组是否全部要包含,and将包含所有词,OR只需要包含任一词就行

  • minimum_should_match(可选,字符串)

    要返回的文档必须匹配的最小子句数:可填数字,百分比:参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-minimum-should-match.html

  • zero_terms_query(可选,字符串,默认none)

    指示如果analyzer 删除所有标记(例如使用stop过滤器时),是否不返回任何文档,可选值:none、all,参考:零条件查询

match_bool_prefix 查询

该查询会构造成一组bool组合查询,将最后一个词作为前缀查询.

例如:
1
2
3
4
5
6
7
{
"query": {
"match_bool_prefix" : {
"message" : "quick brown f"
}
}
}
以上查询相当于下面的查询:
1
2
3
4
5
6
7
8
9
10
11
{
"query": {
"bool" : {
"should": [
{ "term": { "message": "quick" }},
{ "term": { "message": "brown" }},
{ "prefix": { "message": "f"}}
]
}
}
}

前面的分词会被作为term查询,相当于普通分词查询,后面的作为前缀查询(prefix),使用should,满足任何一个条件就会命中

匹配词组查询(Match phrase query)

短语匹配,会将输入的搜索词分词后一 一匹配,当所有词语都匹配上时才返回,并且匹配的词语是挨着的(可通过slop调节)。相当于整句匹配

1
2
3
4
5
6
7
8
9
10
{
"query": {
"match_phrase": {
"name": {
"query": "藿香正气液",
"slop": 0
}
}
}
}

上面只会返回包含“藿香正气液”整句的文档,可通过slop设置两个词之间的间隔位置(默认0,就是紧挨着),也可analyzer指定分词器。

不调整参数使用默认的可以简写:
1
2
3
4
5
6
7
{
"query": {
"match_phrase": {
"name": "藿香正气液"
}
}
}

匹配词组前缀查询

与短语匹配查询(Match phrase query)类似,只不过会把最后一个词作为前缀,类似于补全句子功能,比如:搜索quick brown f 就会匹配到quick brown fox结果,f就是fox的前缀,一般用于即时搜索,用于实时的查询结果。

1
2
3
4
5
6
7
8
9
{
"query": {
"match_phrase_prefix" : {
"message" : {
"query" : "quick brown f"
}
}
}
}
参数 类型 说明 是否必须
query 字符串 输入的文本
analyzer 字符串 分词器,未设置则使用默认的分词器
max_expansions 整数
slop 整数 匹配令牌之间允许的最大位置数。默认为0。转置字词的斜率为2
zero_terms_query 字符串 指示如果analyzer 删除所有标记(例如使用stop过滤器时),是否不返回任何文档。有效值为: none (默认) 如果analyzer删除所有标记,则不会返回任何文档。 all 返回所有文档,类似于match_all 查询

多匹配查询

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

1
2
3
4
5
6
7
8
{
"query": {
"multi_match" : {
"query": "阿莫西林",
"fields": [ "name", "productGeneralName" ]
}
}
}

字段可以使用通配符

1
2
3
4
5
6
7
8
{
"query": {
"multi_match" : {
"query": "阿莫西林",
"fields": [ "name", "*Name" ]
}
}
}

可使用“ ^n ”来增强各个字段提升得分,如下面将name得分提高三倍

1
2
3
4
5
6
7
8
{
"query": {
"multi_match" : {
"query": "阿莫西林",
"fields": [ "name^3", "*Name" ]
}
}
}
  • multi_match 查询类型
类型 说明
best_fields(默认) 使用字段匹配度最高的记录,比如上面name字段匹配度更高,则使用name字段所在文档
most_fields 合并多个匹配字段的得分。得分高的排前面
cross_fields
phrase match_phrase(短语匹配)每个字段,使用分数最高的文档
phrase_prefix match_phrase_prefix(短语前缀匹配)每个字段,使用得分最高的文档
bool_prefix match_bool_prefix 每个字段,并合并每个字段得分
1
2
3
4
5
6
7
8
9
10
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first_name", "last_name" ],
"operator": "and"
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"query": {
"bool": {
"should": [
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first", "last" ],
"minimum_should_match": "50%"
}
},
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "*.edge" ]
}
}
]
}
}
}