100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 从零学Elasticsearch系列——深入搜索(Query Filter Aggregation)

从零学Elasticsearch系列——深入搜索(Query Filter Aggregation)

时间:2018-08-23 08:13:28

相关推荐

从零学Elasticsearch系列——深入搜索(Query Filter Aggregation)

系列文章:

从零学Elasticsearch系列——基础概念从零学Elasticsearch系列——环境搭建从零学Elasticsearch系列——使用kibana实现ES基本的操作从零学Elasticsearch系列——深入搜索(Query、Filter、Aggregation)从零学Elasticsearch系列——JAVA API操作从零学Elasticsearch系列——集成中文分词器IK从零学Elasticsearch系列——构建ES集群从零学Elasticsearch系列——搭建ELK Nginx日志分析平台

搜索方式

搜索有两种方式:一种是通过URL参数进行搜索,另一种是通过DSL(Request Body)进行搜索

DSL:Domain Specified Language,特定领域语言

使用请求体可以让你的JSON数据以一种更加可读和更加富有展现力的方式发送。

导入测试数据集

# 批量插入测试数据POST /zpark/user/_bulk{"index":{"_id":1}}{"name":"zs","realname":"张三","age":18,"birthday":"-12-27","salary":1000.0,"address":"北京市昌平区沙阳路55号"}{"index":{"_id":2}}{"name":"ls","realname":"李四","age":20,"birthday":"-10-20","salary":5000.0,"address":"北京市朝阳区三里屯街道21号"}{"index":{"_id":3}}{"name":"ww","realname":"王五","age":25,"birthday":"-03-15","salary":4300.0,"address":"北京市海淀区中关村大街新中关商城2楼511室"}{"index":{"_id":4}}{"name":"zl","realname":"赵六","age":20,"birthday":"-04-19","salary":12300.0,"address":"北京市海淀区中关村软件园9号楼211室"}{"index":{"_id":5}}{"name":"tq","realname":"田七","age":35,"birthday":"2001-08-11","salary":1403.0,"address":"北京市海淀区西二旗地铁辉煌国际大厦负一楼"}

查询(Query)

1. 查看所有并按照年龄降序排列

查询所有并排序

URL实现

GET /zpark/user/_search?q=*&sort=age:desc&pretty

DSL实现

GET /zpark/user/_search{"query":{"match_all":{}# 查询所有},"sort":{"age":"desc" # 按年龄倒序排列}}

2. 查询第2页的用户(每页显示2条)

分页查询

URL实现

GET /zpark/user/_search?q=*&sort=_id:asc&from=2&size=2

DSL实现

GET /zpark/user/_search{"query":{"match_all":{}# 查询所有},"sort":{"_id":"asc" # 按年龄倒序排列},"from":2,# 从(nowPage-1)*pageSize检索"size":2 # 查 pageSize条}

3. 查询address在海淀区的所有用户,并高亮

基于全文检索的查询(分析检索关键词 匹配索引库 返回结果)

DSL实现

GET /zpark/user/_search{"query": {"match": {# 注意: match查询会分词 如:海淀区 会分词为 海 | 淀 | 区"address":"海淀区"}},"highlight": {"fields": {# 需要高亮的字段列表"address": {} }}}

4. 查询namezs关键字的用户

基于Term词元查询

URL实现

GET /zpark/user/_search?q=name:zs

DSL实现

GET /zpark/user/_search{"query":{"term": {"name": {"value": "zs"}}}}

5. 查询年龄在20~30岁之间的用户

基于范围查询

DSL实现

GET /zpark/user/_search{"query": {"range": {"age": {"gte": 20, # 大于等于 大于用 gt"lte": 30 # 小于等于 小于用 lt}}}}

6. 查询真实姓名以开头的用户

基于前缀(prefix)查询

DSL实现

GET /zpark/user/_search{"query": {"prefix": {"realname": {"value": "李"}}}}

7. 查询名字已s结尾的用户

基于通配符(wildcard)的查询

匹配一个字符*匹配0~n个字符

DSL实现

GET /zpark/user/_search{"query": {"wildcard": {"name": {"value": "*s"}}}}

8. 查询id为1,2,3的用户

基于Ids的查询

DSL实现

GET /zpark/user/_search{"query": {"ids": {"values": [1,2,3]}}}

9. 模糊查询realname中包含关键字的用户

基于Fuzzy的查询

DSL实现

GET /zpark/user/_search{"query": {"fuzzy": {"realname": {"value": "张"}}}}

10. 查询age在15-30岁之间并且name必须通配z*

基于Boolean的查询(多条件查询)

must:查询结果必须符合该查询条件(列表)。should:类似于or的查询条件。must_not:查询结果必须不符合查询条件(列表)。

DSL实现

GET /zpark/user/_search{"query": {"bool": {"must": [ #年龄在15~30岁之间并且必须名字通配z*{"range": {"age": {"gte": 15,"lte": 30}}},{"wildcard": {"name": {"value": "z*"}}}],"must_not": [ # 正则查询 name必须不能以s结尾{"regexp": {"name": ".*s"}}] }}}

过滤器(Filter)

其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)。查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序。而过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档。所以,单从性能考虑,过滤比查询更快。

换句话说,过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,应先使用过滤操作过滤数据,然后使用查询匹配数据。

过滤器使用

GET /zpark/user/_search{"query":{"bool": {"must": [{"match_all": {}}],"filter": {# 过滤年龄大于等于25岁的用户"range": {"age": {"gte": 25}}}}}}

注意: 过滤查询运行时先执行过滤语句,后执行普通查询

过滤器的类型

1.termtermsFilter

term、terms的含义与查询时一致。term用于精确匹配、terms用于多词条匹配

GET /zpark/user/_search{"query":{"bool": {"must": [{"match_all": {}}],"filter": {"terms": {"name": ["zs","ls"]}}}}}

2.ranagefilter
3.existsfilter

exists过滤指定字段没有值的文档

GET /zpark/user/_search{"query": {"bool": {"must": [{"match_all": {}}],"filter": {# 排除salary为null的结果"exists": {"field": "salary"}}}},"sort": [{"_id": {"order": "asc"}}]}

或(相反操作)

GET /zpark/user/_search{"query": {"bool": {"must_not": [{"exists": {"field": "salary"}}]}}}

4.idsfilter

需要过滤出若干指定_id的文档,可使用标识符过滤器(ids)

GET /zpark/user/_search{"query": {"bool": {"must": [{"match": {"address": "昌平区"}}],"filter": {"ids": {# id 过滤器"values": [1,2,3]}}}}}

5. 其余使用方式可查阅官网

Note:

Query和Filter更详细的对比可参考:/laoyang360/article/details/80468757

聚合(Aggregations)

https://www.elastic.co/guide/en/elasticsearch/reference/6.x/search-aggregations.html

聚合提供了功能可以分组并统计你的数据。理解聚合最简单的方式就是可以把它粗略的看做SQL的GROUP BY操作和SQL的聚合函数。

ES中常用的聚合:

metric(度量)聚合:度量类型聚合主要针对的number类型的数据,需要ES做比较多的计算工作,类似于关系型数据库的组函数操作bucketing(桶)聚合:划分不同的“桶”,将数据分配到不同的“桶”里。非常类似sql中的group语句的含义,类似于关系型数据库的分组操作

ES中的聚合API如下:

"aggregations" : {// 表示聚合操作,可以使用aggs替代"<aggregation_name>" : {// 聚合名,可以是任意的字符串。用做响应的key,便于快速取得正确的响应数据。"<aggregation_type>" : {// 聚合类别,就是各种类型的聚合,如min等<aggregation_body>// 聚合体,不同的聚合有不同的body}[,"aggregations" : {[<sub_aggregation>]+ } ]? // 嵌套的子聚合,可以有0或多个}[,"<aggregation_name_2>" : {... } ]* // 另外的聚合,可以有0或多个}

度量(metric)聚合

1. Avg Aggregation

平均值查询,作用于number类型字段上。如:查询用户的平均年龄

POST /zpark/user/_search{"aggs": {"age_avg": {"avg": {"field": "age"}}}}-------------------------------------------------------------------{......"aggregations": {"age_avg": {"value": 23.6}}}

也可以先过滤,再进行统计,如:

POST /zpark/user/_search{"query": {"ids": {"values":[1,2,3]}}, "aggs": {"age_avg": {"avg": {"field": "age"}}}}

2. Max Aggregation

最大值查询。如:查询员工的最高工资

POST /zpark/user/_search{"aggs": {"max_salary": {"max": {"field": "salary"}}}}

3. Min Aggregation
4. Sum Aggregation
5. [Stats Aggregation](Stats Aggregation)

统计查询,一次性统计出某个字段上的常用统计值

POST /zpark/user/_search{"aggs": {"max_salary": {"stats": {"field": "salary"}}}}--------------------------------------------{...."aggregations": {"max_salary": {"count": 4,"min": 1000,"max": 12300,"avg": 5650,"sum": 22600}}}

桶(bucketing)聚合

1. Range Aggregation

自定义区间范围的聚合,我们可以自己手动地划分区间,ES会根据划分出来的区间将数据分配不同的区间上去。

如: 统计0-20岁,20-35岁,35~60岁用户人数

POST /zpark/user/_search{"aggs": {"age_ranges": {"range": {"field": "age","ranges": [{"from": 0,"to": 20},{"from": 20,"to": 35},{"from": 35,"to": 60}]}}}}----------------------------------------------------------{......"aggregations": {"age_ranges": {"buckets": [{"key": "0.0-20.0","from": 0,"to": 20,"doc_count": 1 # 区间范围的文档数量},{"key": "20.0-35.0","from": 20,"to": 35,"doc_count": 3},{"key": "35.0-60.0","from": 35,"to": 60,"doc_count": 1}]}}}

2. Terms Aggregation

自定义分组依据Term,对分组后的数据进行统计

如:根据年龄分组,统计相同年龄的用户

POST /zpark/user/_search{"aggs": {"age_counts":{"terms": {"field": "age","size": 2 // 保留2个统计结果}}}}----------------------------------------------------------{......"aggregations": {"age_counts": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 2,"buckets": [{"key": 20,"doc_count": 2},{"key": 18,"doc_count": 1}]}}}

3. Date Range Aggregation

时间区间聚合专门针对date类型的字段,它与Range Aggregation的主要区别是其可以使用时间运算表达式。

now+10y:表示从现在开始的第。now+10M:表示从现在开始的第10个月。1990-01-10||+20y:表示从1990-01-01开始后的第,即-01-01。now/y:表示在年位上做舍入运算。

如: 统计生日在、、的用户

POST /zpark/user/_search{"aggs": {"date_counts": {"date_range": {"field": "birthday","format": "yyyy-MM-dd", "ranges": [{"from": "now/y", # 当前年的1月1日"to": "now" # 当前时间},{"from": "now/y-1y", # 当前年上一年的1月1日"to":"now/y" # 当前年的1月1日},{"from": "now/y-2y", "to":"now/y-1y"}]}}}}-------------------------------------------------------------------------------{....."aggregations": {"date_counts": {"buckets": [{"key": "-01-01--01-01","from": 1451606400000,"from_as_string": "-01-01","to": 1483228800000,"to_as_string": "-01-01","doc_count": 1},{"key": "-01-01--01-01","from": 1483228800000,"from_as_string": "-01-01","to": 1514764800000,"to_as_string": "-01-01","doc_count": 1},{"key": "-01-01--12-26","from": 1514764800000,"from_as_string": "-01-01","to": 1545847233691,"to_as_string": "-12-26","doc_count": 0}]}}}

4. Histogram Aggregation

直方图聚合,它将某个number类型字段等分成n份,统计落在每一个区间内的记录数。它与前面介绍的Range聚合非常像,只不过Range可以任意划分区间,而Histogram做等间距划分。既然是等间距划分,那么参数里面必然有距离参数,就是interval参数。

如:根据年龄间隔(5岁)统计

POST /zpark/user/_search{"aggs": {"histogram_age": {"histogram": {"field": "age","interval": 5}}}}-------------------------------------------------------------------------------{......"aggregations": {"histogram_age": {"buckets": [{"key": 15,"doc_count": 1},{"key": 20,"doc_count": 2},{"key": 25,"doc_count": 1},{"key": 30,"doc_count": 0},{"key": 35,"doc_count": 1}]}}}

5. Date Histogram Aggregation

日期直方图聚合,专门对时间类型的字段做直方图聚合。这种需求是比较常用见得的,我们在统计时,通常就会按照固定的时间断(1个月或1年等)来做统计。

如:按年统计用户

POST /zpark/user/_search{"aggs": {"date_histogram": {"date_histogram": {"field": "birthday","interval": "year","format": "yyyy-MM-dd"}}}}-------------------------------------------------------------------------------{......"aggregations": {"date_histogram": {"buckets": [{"key_as_string": "2001-01-01","key": 978307200000,"doc_count": 1},{"key_as_string": "2002-01-01","key": 1009843200000,"doc_count": 0},{"key_as_string": "-01-01","key": 1041379200000,"doc_count": 1},{"key_as_string": "-01-01","key": 1072915200000,"doc_count": 0},{"key_as_string": "-01-01","key": 1104537600000,"doc_count": 0},{"key_as_string": "-01-01","key": 1136073600000,"doc_count": 0},{"key_as_string": "-01-01","key": 1167609600000,"doc_count": 0},{"key_as_string": "-01-01","key": 1199145600000,"doc_count": 0},{"key_as_string": "-01-01","key": 1230768000000,"doc_count": 0},{"key_as_string": "-01-01","key": 1262304000000,"doc_count": 0},{"key_as_string": "-01-01","key": 1293840000000,"doc_count": 0},{"key_as_string": "-01-01","key": 1325376000000,"doc_count": 0},{"key_as_string": "-01-01","key": 1356998400000,"doc_count": 0},{"key_as_string": "-01-01","key": 1388534400000,"doc_count": 0},{"key_as_string": "-01-01","key": 140400000,"doc_count": 0},{"key_as_string": "-01-01","key": 1451606400000,"doc_count": 1},{"key_as_string": "-01-01","key": 1483228800000,"doc_count": 1},{"key_as_string": "-01-01","key": 1514764800000,"doc_count": 1}]}}}

嵌套使用

聚合操作是可以嵌套使用的。通过嵌套,可以使得metric类型的聚合操作作用在每一bucket上。我们可以使用ES的嵌套聚合操作来完成稍微复杂一点的统计功能。

如:统计每年中用户的最高工资

POST /zpark/user/_search{"aggs": {"date_histogram": {# bucket聚合 按照年分区"date_histogram": {"field": "birthday","interval": "year","format": "yyyy-MM-dd"},"aggs": {"salary_max": {"max": {# metric聚合 求最大工资"field": "salary"}}}}}}--------------------------------------------------------------------------------------{......"aggregations": {"date_histogram": {"buckets": [......{"key_as_string": "-01-01","key": 1483228800000,"doc_count": 1,"salary_max": {"value": 5000}},{"key_as_string": "-01-01","key": 1514764800000,"doc_count": 1,"salary_max": {"value": 1000}}]}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。