Elasticsearch 学习--高级查询

发布时间 2023-03-27 00:16:13作者: a-tao必须奥利给

Elasticsearch 学习--高级查询

2.2.4.4 高级查询

Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询定义数据 :

# POST /student/_doc/1001
{
"name":"zhangsan",
"nickname":"zhangsan",
 "sex":"男",
 "age":30
}
# POST /student/_doc/1002
{
"name":"lisi",
"nickname":"lisi",
 "sex":"男",
 "age":20
}
# POST /student/_doc/1003
{
"name":"wangwu",
 "nickname":"wangwu",
 "sex":"女",
"age":40
}
# POST /student/_doc/1004
{
"name":"zhangsan1",
"nickname":"zhangsan1",
 "sex":"女",
 "age":50
}
# POST /student/_doc/1005
{
"name":"zhangsan2",
"nickname":"zhangsan2",
 "sex":"女",
 "age":30
}
1) 查询所有文档

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
 "query": {
 "match_all": {}
 }
}
# "query":这里的 query 代表一个查询对象,里面可以有不同的查询属性
# "match_all":查询类型,例如:match_all(代表查询所有), match,term , range 等等
# {查询条件}:查询条件会根据类型的不同,写法也有差异

服务器响应结果如下:

{
    "took【查询花费时间,单位毫秒】": 1116,
    "timed_out【是否超时】": false,
    "_shards【分片信息】": {
        "total【总数】": 1,
        "successful【成功】": 1,
        "skipped【忽略】": 0,
        "failed【失败】": 0
    },
    "hits【搜索命中结果】": {
        "total"【搜索条件匹配的文档总数】: {
            "value"【总命中计数的值】: 3,
            "relation"【计数规则】: "eq" # eq 表示计数准确, gte 表示计数不准确
        },
        "max_score【匹配度分值】": 1.0,
        "hits【命中结果集合】": [
 。。。
        }
    ]
}
}
2) 匹配查询

match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
	 "query": {
		 "match": {
     	 "name":"zhangsan"
 		}
 	}
}

服务器响应结果为:

3) 字段匹配查询

multi_match 与 match 类似,不同的是它可以在多个字段中查询。

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "multi_match": {
            "query": "zhangsan",
            "fields": [
                "name",
                "nickname"
            ]
        }
    }
}

服务器响应结果:

4) 关键字精确查询

term 查询,精确的关键词匹配查询,不对查询条件进行分词。

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "term": {
            "name": {
                "value": "zhangsan"
            }
        }
    }
}

服务器响应结果:

5) 多关键字精确查询

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。

如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于 mysql 的 in

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
 	"query": {
 		"terms": {
			 "name": ["zhangsan","lisi"]
		 }
 	}
}

服务器响应结果:

6) 指定查询字段

默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在_source 的所有字段都返回。

如果我们只想获取其中的部分字段,我们可以添加_source 的过滤

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "_source": [
        "name",
        "nickname"
    ],
    "query": {
        "terms": {
            "nickname": [
                "zhangsan"
            ]
        }
    }
}

服务器响应结果:

7) 过滤字段

我们也可以通过:

 includes:来指定想要显示的字段

 excludes:来指定不想要显示的字段

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "_source": {
        "includes": [
            "name",
            "nickname"
        ]
    },
    "query": {
        "terms": {
            "nickname": [
                "zhangsan"
            ]
        }
    }
}

服务器响应结果:

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "_source": {
        "excludes": [
            "name",
            "nickname"
        ]
    },
    "query": {
        "terms": {
            "nickname": [
                "zhangsan"
            ]
        }
    }
}

服务器响应结果:

8) 组合查询

bool把各种其它查询通过must(必须 )、must_not(必须不)、should(应该)的方

式进行组合

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "name": "zhangsan"
                    }
                }
            ],
            "must_not": [
                {
                    "match": {
                        "age": "40"
                    }
                }
            ],
            "should": [
                {
                    "match": {
                        "sex": "男"
                    }
                }
            ]
        }
    }
}

服务器响应结果:

9) 范围查询

range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "range": {
            "age": {
                "gte": 30,
                "lte": 35
            }
        }
    }
}

服务器响应结果:

10) 模糊查询

返回包含与搜索字词相似的字词的文档。

编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:

​  更改字符(box → fox)

​  删除字符(black → lack)

​  插入字符(sic → sick)

​  转置两个相邻字符(act → cat)

为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体

或扩展。然后查询返回每个扩展的完全匹配。

通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "fuzzy": {
            "title": {
                "value": "zhangsan"
            }
        }
    }
}

服务器响应结果:

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "fuzzy": {
            "title": {
                "value": "zhangsan",
                "fuzziness": 2
            }
        }
    }
}

服务器响应结果:

11) 单字段排序

sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc升序。

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "match": {
            "name": "zhangsan"
        }
    },
    "sort": [
        {
            "age": {
                "order": "desc"
            }
        }
    ]
}

服务器响应结果:

12) 多字段排序

假定我们想要结合使用 age 和 _score 进行查询,并且匹配的结果首先按照年龄排序,然后按照相关性得分排序

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "match_all": {}
    },
    "sort": [
        {
            "age": {
                "order": "desc"
            }
        },
        {
            "_score": {
                "order": "desc"
            }
        }
    ]
}

服务器响应结果:

13) 高亮查询

在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。

Elasticsearch 可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。

在使用 match 查询的同时,加上一个 highlight 属性:

 pre_tags:前置标签

 post_tags:后置标签

 fields:需要高亮的字段

 title:这里声明 title 字段需要高亮,后面可以为这个字段设置特有配置,也可以空

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "match": {
            "name": "zhangsan"
        }
    },
    "highlight": {
        "pre_tags": "<font color='red'>",
        "post_tags": "</font>",
        "fields": {
            "name": {}
        }
    }
}

服务器响应结果:

14) 分页查询

from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size

size:每页显示多少条

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "query": {
        "match_all": {}
    },
    "sort": [
        {
            "age": {
                "order": "desc"
            }
        }
    ],
    "from": 0,
    "size": 2
}

服务器响应结果:

15) 聚合查询

聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很

多其他的聚合,例如取最大值、平均值等等。

 对某个字段取最大值 max

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
 "aggs":{
 "max_age":{
 "max":{"field":"age"}
 }
 },
 "size":0
}

服务器响应结果:

 对某个字段求和 sum

 对某个字段取平均值 avg

 State 聚合

stats 聚合,对某个字段一次性返回 count,max,min,avg 和 sum 五个指标

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
 "aggs":{
 "stats_age":{
 "stats":{"field":"age"}
 }
 },
 "size":0
}

服务器响应结果:

16) 桶聚合查询

桶聚和相当于 sql 中的 group by 语句

 terms 聚合,分组统计

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
    "aggs": {
        "age_groupby": {
            "terms": {
                "field": "age"
            }
        }
    },
    "size": 0
}

服务器响应结果:

 在 terms 分组下再进行聚合

在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search

{
 "aggs":{
 "age_groupby":{
 "terms":{"field":"age"}
 }
 },
 "size":0
}