elasticsearch 查询语言 Query DSL

Query DSL

Domain Specific Language

某种领域中特定的查询语言,这是是指 elasticsearch 中的 query 语言

Query and filter context

一段查询语句的结果集取决于其中所使用的 查询内容 query context过滤内容 filter context

Query context

How well does this document match this query clause?

这个文档内容匹配查询语句结果怎么样?

注意,查询结果中的 score 受 query context 影响。

Filter context

Does this document match this query clause?

这个文档内容匹配这个查询语句吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET *nginx*/_search
{
"query": {
"bool": {
"must": [
{ "match": { "nginx.access.url": "/favicon.ico" }}
],
"filter": [
{ "term": { "nginx.access.method": "GET" }},
{ "range": { "nginx.access.body_sent.bytes": { "gte": 3000 }}}
]
}
}
}
  • 整个 query 属于查询内容 query context
  • bool 和 match 被用于 query context 中,会影响查询分数
  • filter 用于过滤查询内容
  • term 和 range 被用于 filter context 中,不会影响分数

Match All Query

Match All Query

最简单的查询方式。查询所有匹配的 documents,如果全部查询出来,则 _score = 1.0

1
2
3
4
5
6
GET *nginx*/_search
{
"query": {
"match_all": {}
}
}

可以设置 boost 来改变结果分数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET *nginx*/_search
{
"query": {
"match_all": {
"boost" : 1.2
}
}
}

"hits" : {
"total" : 8,
"max_score" : 1.2,
"hits" : [
{
"_score" : 1.2,
}
]
}

Match None Query

是 match_all 的反例

1
2
3
4
5
6
GET *nginx*/_search
{
"query": {
"match_none":{}
}
}
1
2
3
4
5
6
7
{
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}

Full text queries

全文查询允许搜索分析文本字段,在索引中,利用查询字符串处理相同的分析器。

预存数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /eminoda_test/_doc
{
"name":"eminoda",
"age":30,
"skill":"vue node"
}

POST /eminoda_test/_doc
{
"name":"mike",
"age":40,
"skill":"angular node"
}

POST /eminoda_test/_doc
{
"name":"cc",
"age":50,
"skill":"reactive jquery"
}

match query

The standard query for performing full text queries, including fuzzy matching and phrase or proximity queries.

这是个标准的查询匹配方式来进行全文匹配,包括模糊,短语,近似查询。

match 接受 text/numerics/dates ,构造一个查询请求,并且分析查询结果。

查询 eminoda_test 索引,documents 中字段为 name ,值为 eminoda 的结果:

1
2
3
4
5
6
7
8
GET /eminoda_test/_search
{
"query": {
"match": {
"name": "eminoda"
}
}
}
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
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "DP1sz2sBqZI9Rs_eLn_H",
"_score" : 0.2876821,
"_source" : {
"name" : "eminoda",
"age" : 30,
"skill" : "vue node"
}
}
]
}
}

match query 处理结果是 bool 类型。会构造一个 bool 的查询对 text 文本的分析结果进行返回,默认会对 text 的内容进行 or 操作(有 or 和 and)。

默认搜索器:default search analyzer

比如,skill = jquery node 会返回 3 条记录:

1
2
3
4
5
6
7
8
GET /eminoda_test/_search
{
"query": {
"match": {
"skill": "jquery node"
}
}
}
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
"hits" : {
"total" : 3,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "Df1sz2sBqZI9Rs_eNn-v",
"_score" : 0.2876821,
"_source" : {
"name" : "mike",
"age" : 40,
"skill" : "angular node"
}
},
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "Dv1sz2sBqZI9Rs_ePn_E",
"_score" : 0.2876821,
"_source" : {
"name" : "cc",
"age" : 50,
"skill" : "reactive jquery"
}
},
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "DP1sz2sBqZI9Rs_eLn_H",
"_score" : 0.2876821,
"_source" : {
"name" : "eminoda",
"age" : 30,
"skill" : "vue node"
}
}
]
}

如果设置 operator = and ,则会对结果有影响:

1
2
3
4
5
6
7
8
9
10
11
GET /eminoda_test/_search
{
"query": {
"match": {
"skill": {
"query": "jquery node",
"operator":"and"
}
}
}
}
1
2
3
4
5
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}

fuzziness 允许对模糊查询,并可以设置模糊度。规范讲应该是:Levenshtein Edit Distance

如,允许对 skill 的 text “出错” 2 个字符:

1
2
3
4
5
6
7
8
9
10
11
GET /eminoda_test/_search
{
"query": {
"match": {
"skill":{
"query":"angularjs",
"fuzziness": 2
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"hits" : {
"total" : 1,
"max_score" : 0.2054872,
"hits" : [
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "Df1sz2sBqZI9Rs_eNn-v",
"_score" : 0.2054872,
"_source" : {
"name" : "mike",
"age" : 40,
"skill" : "angular node"
}
}
]
}

match_phrase query

Like the match query but used for matching exact phrases or word proximity matches.

和 match query 类似,但多用于匹配短语 or 单词的接近匹配。

如果用 match 方式,则会返回 三条 记录,此匹配会以 text 内容做精确匹配

1
2
3
4
5
6
7
8
GET /eminoda_test/_search
{
"query": {
"match_phrase": {
"skill": "jquery node"
}
}
}
1
2
3
4
5
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}

match_phrase_prefix query

Like the match_phrase query, but does a wildcard search on the final word.

和 match_phrase query 类似,但通过通配符作用于最后个单词匹配

1
2
3
4
5
6
7
8
GET /eminoda_test/_search
{
"query": {
"match_phrase_prefix": {
"skill": "a"
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"hits" : {
"total" : 1,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "Df1sz2sBqZI9Rs_eNn-v",
"_score" : 0.2876821,
"_source" : {
"name" : "mike",
"age" : 40,
"skill" : "angular node"
}
}
]
}

match_bool_prefix query

Creates a bool query that matches each term as a term query, except for the last term, which is matched as a prefix query

创建一个 bool 查询来匹配查询结果,除了最后一个作为前缀查询匹配

multi_match query

The multi-field version of the match query.

多结果匹配查询

1
2
3
4
5
6
7
8
9
GET /eminoda_test/_search
{
"query": {
"multi_match": {
"query": "eminoda learn angular",
"fields": ["name","skill"]
}
}
}
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
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "Df1sz2sBqZI9Rs_eNn-v",
"_score" : 0.2876821,
"_source" : {
"name" : "mike",
"age" : 40,
"skill" : "angular node"
}
},
{
"_index" : "eminoda_test",
"_type" : "_doc",
"_id" : "DP1sz2sBqZI9Rs_eLn_H",
"_score" : 0.2876821,
"_source" : {
"name" : "eminoda",
"age" : 30,
"skill" : "vue node"
}
}
]
}

common terms query

A more specialized query which gives more preference to uncommon words.

更特殊的查询方式,针对不友好的单词。

query_string query

Supports the compact Lucene query string syntax, allowing you to specify AND|OR|NOT conditions and multi-field search within a single query string. For expert users only.

支持 Lucene 查询字符串语法,允许使用特殊的条件(and、or、not),和多条件的搜索一个简单的查询字符串。

1
2
3
4
5
6
7
8
9
GET /eminoda_test/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "mike or eminoda"
}
}
}

simple_query_string query

A simpler, more robust version of the query_string syntax suitable for exposing directly to users.

intervals query

A full text query that allows fine-grained control of the ordering and proximity of matching terms

细粒度控制相近匹配结果

最后

以上列出目前使用过的几种,其他方式未花时间做过多实践。可结合官网在做深入。

【长按关注】看看↓↓↓?
Eminoda wechat
【前端雨爸】分享前端技术实践,持续输出前端技术文章
欢迎留言,评论交流,一起讨论前端问题
📢 因为是开源博客,为避免 Gitalk授权 带来的 安全风险,也可访问