Elasticsearch中的常用查询语句示例
前记
由于公司内部的研发团队越来越多的接触到复杂的查询需求,也越来越多的依赖大数据部门提供的es搜索引擎提供查询服务
特此整理一些es常用的查询语句用于培训,目的在于帮助其他不熟悉es的同学快速熟悉es的dsl语句的编写
数据初始化和准备工作
es和kibana安装
可以从 https://github.com/leriou/docker-env/tree/master/elasticsearch
直接使用docker编排文件构建基于docker的es本地服务
docker-compose up -d
启动服务,启动成功访问kibana命令控制台
es: elasticsearch 实例,主要存储和搜索引擎
kibana: elasticsearch的一个web层GUI客户端,可以方便的查询es里面的数据,这些年用了一大堆各种各样的第三方GUI,用来用去还是kibana最方便
准备测试数据
先准备一部分数据用于演示
创建测试用的索引put test_idx
创建测试文档
1 | put test_idx/_doc/1 |
以下是用于示范的数据文档
1 | [ |
简单查询示范
n对n查询
1 | 1对1匹配查询:适用于 查询条件为1个值,被查询对象字段也为1个值的情况 |
1 | 1对多查询:适用于 查询条件为一个,查询值为[]的情况 |
1 | 多对1查询:适用于查询条件为[],被查询字段为1个值的情况 |
1 | 多对多查询:适用于查询条件为 [], 查询值也为[] 的情况 |
万能匹配-match
match
查询可以用于多种查询用途,常见的全文检索,关键词匹配等都使用该方法,是es中最常用的查询
1 | where tags.contains("a") |
其他常用查询(range, exist, a and b等)
1 | 范围查询 where a between 10 and 20 |
查询原理解析
es文档字段的存储逻辑
es中的字段看起来有多种数据结构,实际抽象出来只有一种数据结构就是 k-v
1 | 类似 |
match
为什么可以做到万能查询
是因为match在查询时候会对查询条件进行分词
1 | 不分词的查询查不到 tags:["a","b"]的值, 只能查询到 tags:["ab"]的值 |
ps: es自带了一部分内容格式转换规则,类似 type = “VIDEO” 这种字段如果要使用term查询的话需要用 term:{type.keyword:”VIDEO”}, 因为大写的字段值会被默认分词, 如果是type =”video”这种小写 就可以用 term:{type:”video”}来进行匹配
分值相关查询
有时候我们希望按照某种特殊的顺序对es的文档进行排序,这个时候往往需要自定义文档查询得分
filter过滤
1 | filter使用布隆过滤器进行过滤所以没有分值,性能较好 |
constant_score和boost提权
constant_score
用于指定查询命中的单位得分值,每个查询价值一个分值单位
boost
用于提升权重
1 | 该查询命中则价值 1.2分 且忽略tf/idf得分 |
function_score
function_score
自定义分值,可以根据文档内容进行得分定制
1 | 该查询根据文档的age字段 * 5 作为最终分值 |
查询示例:根据用户关注的标签匹配数量计算得分
1 | 假设用户关注了["a","b"] 标签,根据用户的关注标签匹配数量进行分数计算,a标签价值1.3分,b标签1.1 |
聚合查询
terms求count值
1 | 等价于 group by tags |
avg求平均值
1 | GET test_idx/_search |
其他查询和dsl
原子更新文档
1 | 由于es本身不支持源字形的更新文档,我们需要借助内置脚本的帮助来操作 |
explain
explain 用于查看查询的执行过程和各部分的具体得分,一般用于排查问题
1 | GET test_idx/_search |
参考资料
https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html