对es查询的索引的company,其有如下字段,下面是一个示例数据

"id": "1", //id
"name": "张三",//姓名
"sex": "男",//性别
"age": 49,//年龄
"birthday": "1970-01-01",//生日
"position": "董事长",//职位
"joinTime": "1990-01-01",//入职时间,日期格式
"modified": "1562167817000",//修改时间,毫秒
"created": "1562167817000"  //创建时间,毫秒

下面的搜索都会将关系型数据库语句转换成es的搜索api以及参数。

主要是用post方式,用DSL(结构化查询)语句进行搜索。

一、查询

1、简单搜索

【sql】select * from company
【ES】有两种方式1、GET http://192.168.197.100:9200/company/_search2、POST http://192.168.197.100:9200/company/_search{"query":{"match_all":{}}}

2、精确匹配(不对查询文本进行分词)

【sql】select * from company where name='张三'
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"term":{"name.keyword":"张三"}}}

term是用于精确匹配的,类似于sql语句中的“=”,因为“name”字段用的是standard默认分词器,其会将“张三”分成“张”和“三”,并不会匹配姓名为“张三”的人,而name.keyword可以让其不会进行分词。

也可以是terms,这个可以用多个值去匹配一个字段,例如

【sql】select * from company where name in ('张三','李四')
【ES】POST http://192.168.197.100:9200/company/_search{"query": {"terms": {"name.keyword": ["张三", "李四"]}}}

3、模糊匹配

【sql】select * from company where name like '%张%'
【ES】POST http://192.168.197.100:9200/company/_search{"query": {"match": {"name": "张"}}}

上述查询会查出姓名中带有“张”字的文档

4、分页查询

【sql】select * from company limit 0,10
【ES】POST http://192.168.197.100:9200/company/_search{"from":0,"size":10}

【注意】from+size不能大于10000,也可以进行修改,但不建议这么操作,因为es主要分片模式,其会在每个分片都会执行一样的查询,然后再进行汇总排序,如果数据太大,会撑爆内存。例如每个分片都查询出10000条,总共5个分片,最后就会进行50000条数据的排序,最后再取值。

5、范围查询并进行排序

【sql】select * from company where age>=10 and age<=50
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"range":{"age":{"gte":10,"lte":50}}},"sort":{"age":{"order":"desc"}}}

范围查询是range,有四种参数

(1)gte:大于等于

(2)gt:大于

(3)lte:小于等于

(4)lt:小于

排序是sort,降序是desc,升序是asc,可以有多个排序字段

6、多字段匹配查询

【sql】select * from company where sex like '%男%' or name like '%男%'
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"multi_match":{"query":"男","fields":["name","sex"]}}}

7、bool查询(结构化查询)

结构化查询主要有三块,分别是must,should,must_not,filter

(1)must:里面的条件都是“并”关系,都匹配

(2)should:里面的条件都是“或”关系,有一个条件匹配就行

(3)must_not:里面的条件都是“并”关系,都不能匹配

(4)filter:过滤查询,不像其它查询需要计算_score相关性,它不进行此项计算,故比query查询快

例如:

条件:

年龄在10到50,性别是男

性别一定不能是女

id是1~8的或者职位带有“董”字的

【sql】select * from company where (age>=10 and age=50 and sex="男")and (sex!="女") and (id in (1,2,3,4,5,6,7,8) or position like '%董%')and departments in ('市场部')
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"bool":{"must":[{"term":{"sex":"男"}},{"range":{"age":{"gte":10,"lt":50}}}],"must_not":[{"term":{"sex":"女"}}  ],"should":[{"terms":{"id":[1,2,3,4,5,6,7,8]}},{"match":{"position":"董"}}],"filter":[{"match":{"departments.keyword":"市场部"}}  ]}}}

另外,bool查询是可以嵌套的,也就是must、must_not、should、filter里面还可以嵌套一个完整的bool查询。

8、通配符查询

?:只匹配一个字符

*:匹配多个字符

【sql】select * from company where departments like '%部'
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"wildcard":{"departments.keyword":"*部"}}}

9、前缀查询

【sql】select * from company where departments like '市%'
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"match_phrase_prefix":{"departments.keyword":"市"}}}

10、查询空值(null)

比如我添加一个文档,里面没有sex字段或者添加的时候sex字段为null,这种情况该怎么进行查询呢?

//添加文档
POST http://192.168.197.100:9200/company/_doc
//没有sex字段的文档{"id": "1","name": "张十","age": 54,"birthday": "1960-01-01","position": "程序员","joinTime": "1980-01-01","modified": "1562167817000","created": "1562167817000"
}//sex字段值为null的文档{"id": "1","name": "张十一","age": 64,"sex":null,"birthday": "1960-01-01","position": "程序员","joinTime": "1980-01-01","modified": "1562167817000","created": "1562167817000"
}

这两种情况的查询是一样的,都是用exists查询匹配,例如:下面的查询会匹配出上述添加的两个文档。

【sql】select * from company where sex is null
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"bool":{"must_not":[{"exists":{"field":"sex"}}]}}}

二、过滤(在es5之后被去除了)

过滤跟查询很相似,都是用来查询数据,只不过过滤会维系一个缓存数组,数组里面记录了匹配的文档,比如一个索引下面有两个文档,进行过滤,一个匹配,一个不匹配,那么数组是这样的[1,0],匹配的文档为1。

在频繁查询的时候,建议用过滤而不是索引。

过滤跟查询的请求体基本相似,只不过多嵌套了一层filtered。

例如:

【sql】select * from company where departments like '%市%'
【ES】POST http://192.168.197.100:9200/company/_search{"query":{"filtered":{"filter":{"match":{"departments.keyword":"市"}}}}}

三、聚合

聚合允许使用者对es文档进行统计分析,类似与关系型数据库中的group by,当然还有很多其他的聚合,例如取最大值、平均值等等。

语法如下:

POST http://192.168.197.100:9200/company/_search
{"aggs": {"NAME": { //指定结果的名称"AGG_TYPE": { //指定具体的聚合方法,TODO:  //# 聚合体内制定具体的聚合字段}}TODO:  //该处可以嵌套聚合}
}

聚合分析功能主要有指标聚合、桶聚合、管道聚合和矩阵聚合,常用的有指标聚合和桶聚合,本文主要看一下指标聚合和桶聚合怎么使用。

1、指标聚合

(1)对某个字段取最大值max

【sql】select max(age) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"max_age":{"max":{"field":"age"}}},"size":0 //size=0是为了只看聚合结果}

结果如下:

{"aggregations": {"max_age": {"value": 64}}
}

(2)对某个字段取最小值min

【sql】select min(age) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"min_age":{"min":{"field":"age"}}},"size":0}

结果如下:

{"aggregations": {"min_age": {"value": 1}}
}

(3)对某个字段计算总和sum

【sql】select sum(age) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sum_age":{"sum":{"field":"age"}}},"size":0}

结果如下:

{"aggregations": {"sum_age": {"value": 315}}
}

(4)对某个字段的值计算平均值

【sql】select avg(sex) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"age_avg":{"avg":{"field":"age"}}},"size":0}

结果如下:

{"aggregations": {"age_avg": {"value": 35}}
}

(5)对某个字段的值进行去重之后再取总数

【sql】select count(distinct(sex)) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_distinct":{"cardinality":{"field":"sex"}}},"size":0}

结果如下:

{"aggregations": {"sex_distinct": {"value": 2}}
}

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

【sql】select count(distinct age),sum(age),avg(age),max(age),min(age) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"age_stats":{"stats":{"field":"age"}}},"size":0}

结果如下:

{"aggregations": {"age_stats": {"count": 9,"min": 1,"max": 64,"avg": 35,"sum": 315}}
}

(7)extended stats聚合,比stats聚合高级一点,多返回平方和、方差、标准差、平均值加/减两个标准差的区间

【sql】--这个的sql不会写,数学专业的人公式都忘了,耻辱
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"age_extended_stats":{"extended_stats":{"field":"age"}}},"size":0}

结果如下:

{"aggregations": {"age_extended_stats": {"count": 9,"min": 1,"max": 64,"avg": 35,"sum": 315,"sum_of_squares": 13857,"variance": 314.6666666666667,"std_deviation": 17.73884626086676,"std_deviation_bounds": {"upper": 70.47769252173353,"lower": -0.4776925217335233}}}
}

(8)percentiles聚合,对某个字段的值进行百分位统计

【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"age_percentiles":{"percentiles":{"field":"age"}}},"size":0}

结果如下:

{"aggregations": {"age_percentiles": {"values": {"1.0": 1,"5.0": 1,"25.0": 26,"50.0": 29,"75.0": 50.25,"95.0": 64,"99.0": 64}}}
}

(9)value count聚合,统计文档中有某个字段的文档数量

【sql】select sum(case when sex is null then 0 else 1 end) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_value_count":{"value_count":{"field":"sex"}}},"size":0}

结果如下:总共有8个文档,我在之前添加了两个没有sex字段的文档

【sql】select sum(case when sex is null then 0 else 1 end) from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_value_count":{"value_count":{"field":"sex"}}},"size":0}

2、桶聚合

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

(1)terms聚合,分组统计

【sql】select sex,count(1) from company group by sex
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_groupby":{"terms":{"field":"sex"}}},"size":0}

结果如下:

{    "aggregations": {"sex_groupby": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "男","doc_count": 5},{"key": "女","doc_count": 1}]}}
}

(2)可以在terms分组下再对其他字段进行其他聚合

【sql】SELECT name,count(1),AVG(age) from company group by name
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_groupby":{"terms":{"field":"sex"},"aggs":{"avg_age":{"avg":{"field":"age"}}}}},"size":0}

结果如下:

{"aggregations": {"sex_groupby": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "男","doc_count": 5,"avg_age": {"value": 33.8}},{"key": "女","doc_count": 1,"avg_age": {"value": 27}}]}}
}

(3)filter聚合,过滤器聚合,对符合过滤器中条件的文档进行聚合

【sql】select sum(age) from company where sex = '男'
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_filter":{"filter":{"term":{"sex":"男"}},"aggs":{"sum_age":{"sum":{"field":"age"}}}}},"size":0
}

结果如下:

{"aggregations": {"sex_filter": {"doc_count": 5,"sum_age": {"value": 169}}}
}

(4)filters多过滤器聚合

【sql】SELECT name,count(1),sum(age) from company group by name
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"sex_filter":{"filters":{"filters":[{"term":{"sex":"男"}},{"term":{"sex":"女"}}]},"aggs":{"sum_age":{"sum":{"field":"age"}}}}},"size":0
}

结果如下:

{"aggregations": {"sex_filter": {"buckets": [{"doc_count": 5,"sum_age": {"value": 169}},{"doc_count": 1,"sum_age": {"value": 27}}]}}
}

(6)range范围聚合,用于反映数据的分布情况

【sql】SELECT sum(case when age<=30 then 1 else 0 end), sum(case when age>30 and age<=50 then 1 else 0 end),sum(case when age>50 then 1 else 0 end)from company
【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"age_range":{"range":{"field":"age","ranges":[{"to":30},{"from":30,"to":50},{"from":50}]}}},"size":0
}

结果如下:

{"aggregations": {"age_range": {"buckets": [{"key": "*-30.0","to": 30,"doc_count": 5},{"key": "30.0-50.0","from": 30,"to": 50,"doc_count": 2},{"key": "50.0-*","from": 50,"doc_count": 2}]}}
}

(7)missing聚合,空值聚合,可以统计缺少某个字段的文档数量

【sql】SELECT count(1) from company where sex is null【ES】POST http://192.168.197.100:9200/company/_search{"aggs":{"missing_sex":{"missing":{"field":"sex"}}},"size":0
}

结果如下:

{"aggregations": {"missing_sex": {"doc_count": 4}}
}

这个也可以用filter过滤器查询,例如:得到的结果是一样的

POST http://192.168.197.100:9200/company/_search{"aggs":{"missing_sex":{"filter":{"bool":{"must_not":[{"exists":{"field":"sex"}  }]}}}},"size":0
}

ok,上述就是ES常用的查询和聚合操作。(看来要深入研究一下es了)

=======================================================

我是Liusy,一个喜欢健身的程序员。

欢迎关注微信公众号【Liusy01】,一起交流Java技术及健身,获取更多干货。

bool查询原理 es_吐血整理:一文看懂ES的R,查询与聚合相关推荐

  1. 一图看懂 docx 读取、查询、修改 Ms Word docx 文件, 资料整理+笔记(大全)

    本文由 大侠(AhcaoZhu)原创,转载请声明. 链接: https://blog.csdn.net/Ahcao2008 一图看懂 docx 读取.查询.修改 Ms Word docx 文件, 资料 ...

  2. 一文看懂Android APK安装的原理

    一文看懂Android APK安装的原理 前言 APK包的构成 安装APK 总结 前言 大家有没有想过一个应用的APK是怎么被安装到安卓手机上的,安装的本质是什么?我们知道,Windows应用程序的安 ...

  3. 一文看懂RPA的技术原理、产品形态、设计与构建

    一文看懂RPA的技术原理.产品形态.设计与构建 过去的一年,RPA机器人流程自动化行业迎来了一个快速发展的机遇.RPA创业者得到了国内投资人的认可,一些RPA公司也接连拿到千万美金级别的融资,这在当下 ...

  4. 天线巴伦制作和原理_一文看懂巴伦(功能原理、性能参数、基本类型)

    原标题:一文看懂巴伦(功能原理.性能参数.基本类型) 巴伦(英语为balun)为一种三端口器件,或者说是一种通过将匹配输入转换为差分输出而实现平衡传输线电路与不平衡传输线电路之间的连接的宽带射频传输线 ...

  5. 一文看懂-ElasticSearch全文搜索引擎

    一文看懂-ElasticSearch全文搜索引擎 一.ElasticSearch简介 1.1 什么是ElasticSearch ElasticSearch简称ES,其中Elastic 从名字里我们可以 ...

  6. 一文看懂“声纹识别VPR” | AI产品经理需要了解的AI技术概念_团员分享_@cony

    前言:声纹识别是AI领域中一个看似很小.但其实有机会在近期落地,且比较有意思的细分方向:本文作者是"AI产品经理大本营"团员@cony  ,她总结了AI产品经理"最必要& ...

  7. 判别两棵树是否相等 设计算法_一文看懂生成对抗网络 - GANs?(附:10种典型算法+13种应用)...

    生成对抗网络 – GANs 是最近2年很热门的一种无监督算法,他能生成出非常逼真的照片,图像甚至视频.我们手机里的照片处理软件中就会使用到它. 本文将详细介绍生成对抗网络 – GANs 的设计初衷.基 ...

  8. 「最有用」的特殊大数据:一文看懂文本信息系统的概念框架及功能

    导读:作为一种特殊的大数据,文本数据泛指各种以自然语言形式存在的数据. 目前,我们正处在一个以大数据与人工智能技术为核心的新的工业革命时代,其主要特征是大量各种可利用的数据可以视为一种特殊的生产资料, ...

  9. 一文看懂JUC之AQS机制

     作者:VectorJin juejin.cn/post/6844904041760161806 为了解决原子性的问题,Java加入了锁机制,同时保证了可见性和顺序性.JDK1.5的并发包中新增了Lo ...

最新文章

  1. vue当前浏览器是否为ie_Vue进阶(六十八):JS-判断当前浏览器是否为IE
  2. [转]json2.js 源码解读
  3. 业界首发|阿里云重磅发布云原生架构白皮书
  4. boost::shared_ptr相关的测试程序
  5. 跨界会对电商行业造成什么影响
  6. android程序运行无操作一段时间显示屏保
  7. STL13-list容器(链表)
  8. 更简洁的方式修改Chrome的User Agent,轻松体验移动版网络
  9. c++《VS2008 快捷键大全》
  10. 冬天你的车热的正确吗?如何正确热车?
  11. svm分类代码_SVM的原理及实现垃圾邮件分类代码解析:
  12. Python 深度学习常用包汇总
  13. 机器非正常关机 出现ora-01033 oracle,oracle ORA-01033问题的解决办法
  14. C# 操作Word文本框——插入图片、表格、文字、超链接等
  15. C/C++, STM32,KEIL warning: #175-D: subscript out of range
  16. Java8 新特性之流式数据处理
  17. 人工智能对人类有哪些影响 选择Python入门怎样
  18. 二级建造师继续教育留念
  19. #1265 - Data truncated for column
  20. ROS与Web交互控制显示

热门文章

  1. c语言5的阶乘流程图_2020年,5种将死的编程语言!
  2. Halcon - 定位 - 卡尺
  3. thinkphp如果表名有下划线需要用Model
  4. 1724: [Usaco2006 Nov]Fence Repair 切割木板( 贪心 )
  5. Node.js缓冲模块Buffer
  6. Microsoft Accelerator for Windows Azure给我们的启示,由 TechStars 撰写
  7. [基础题]4、设计一个家政服务规范: 洗衣服, 扫地, 买菜, 做饭
  8. 16g版nexus5 升级带android 4.4,Nexus 5升级如何Android 4.4.1 Nexus 5升级到4.4.1方法教程
  9. LeetCode Algorithm 386. 字典序排数
  10. python移除系统多余大文件