本篇为学习DSL时做的笔记,适合ES新手,大佬请略过~

Query DSL又叫查询表达式,是一种非常灵活又富有表现力的查询语言,采用JSON接口的方式实现丰富的查询,并使你的查询语句更灵活、更精确、更易读且易调试

查询与过滤

Elasticsearch(以下简称ES)中的数据检索分为两种情况:查询和过滤。

Query查询会对检索结果进行评分,注重的点是匹配程度,例如检索“运维咖啡吧”与文档的标题有多匹配,计算的是查询与文档的相关程度,计算完成之后会算出一个评分,记录在_score字段中,并最终按照_score字段来对所有检索到的文档进行排序

Filter过滤不会对检索结果进行评分,注重的点是是否匹配,例如检索“运维咖啡吧”是否匹配文档的标题,结果只有匹配或者不匹配,因为只是对结果进行简单的匹配,所以计算起来也非常快,并且过滤的结果会被缓存到内存中,性能要比Query查询高很多

简单查询

一个最简单的DSL查询表达式如下:

GET /_search
{
"query":{
"match_all": {}
}
}

/_search 查找整个ES中所有索引的内容

query 为查询关键字,类似的还有aggs为聚合关键字

match_all 匹配所有的文档,也可以写match_none不匹配任何文档

返回结果:

{
"took": 6729,
"timed_out": false,
"num_reduce_phases": 6,
"_shards": {
"total": 2611,
"successful": 2611,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 7662397664,
"max_score": 1,
"hits": [
{
"_index": ".kibana",
"_type": "doc",
"_id": "url:ec540365d822e8955cf2fa085db189c2",
"_score": 1,
"_source": {
"type": "url",
"updated_at": "2018-05-09T07:19:46.075Z",
"url": {
"url": "/app/kibana",
"accessCount": 0,
"createDate": "2018-05-09T07:19:46.075Z",
"accessDate": "2018-05-09T07:19:46.075Z"
}
}
},
...省略其他的结果...
]
}
}

took: 表示我们执行整个搜索请求消耗了多少毫秒

timed_out: 表示本次查询是否超时

这里需要注意当timed_out为True时也会返回结果,这个结果是在请求超时时ES已经获取到的数据,所以返回的这个数据可能不完整。

且当你收到timed_out为True之后,虽然这个连接已经关闭,但在后台这个查询并没有结束,而是会继续执行

_shards: 显示查询中参与的分片信息,成功多少分片失败多少分片等

hits: 匹配到的文档的信息,其中total表示匹配到的文档总数,max_score为文档中所有_score的最大值

hits中的hits数组为查询到的文档结果,默认包含查询结果的前十个文档,每个文档都包含文档的_index_type_id_score_source数据

结果文档默认情况下是按照相关度(_score)进行降序排列,也就是说最先返回的是相关度最高的文档,文档相关度意思是文档内容与查询条件的匹配程度,上边的查询与过滤中有介绍

指定索引

上边的查询会搜索ES中的所有索引,但我们通常情况下,只需要去固定一个或几个索引中搜索就可以了,搜索全部无疑会造成资源的浪费,在ES中可以通过以下几种方法来指定索引

  1. 指定一个固定的索引,ops-coffee-nginx-2019.05.15为索引名字
GET /ops-coffee-nginx-2019.05.15/_search

以上表示在ops-coffee-nginx-2019.05.15索引下查找数据

  1. 指定多个固定索引,多个索引名字用逗号分割
GET /ops-coffee-nginx-2019.05.15,ops-coffee-nginx-2019.05.14/_search
  1. 用*号匹配,在匹配到的所有索引下查找数据
GET /ops-coffee-nginx-*/_search

当然这里也可以用逗号分割多个匹配索引

分页查询

上边有说到查询结果hits默认只展示10个文档,那我们如何查询10个以后的文档呢?ES中给了sizefrom两个参数

size: 设置一次返回的结果数量,也就是hits中的文档数量,默认为10

from: 设置从第几个结果开始往后查询,默认值为0

GET /ops-coffee-nginx-2019.05.15/_search
{
"size": 5,
"from": 10,
"query":{
"match_all": {}
}
}

以上查询就表示查询ops-coffee-nginx-2019.05.15索引下的所有数据,并会在hits中显示第11到第15个文档的数据

全文查询

上边有用到一个match_all的全文查询关键字,match_all为查询所有记录,常用的查询关键字在ES中还有以下几个

match

最简单的查询,下边的例子就表示查找hostops-coffee.cn的所有记录

GET /ops-coffee-2019.05.15/_search
{
"query":{
"match": {
"host":"ops-coffee.cn"
}
}
}

multi_match

在多个字段上执行相同的match查询,下边的例子就表示查询hosthttp_referer字段中包含ops-coffee.cn的记录

GET /ops-coffee-2019.05.15/_search
{
"query":{
"multi_match": {
"query":"ops-coffee.cn",
"fields":["host","http_referer"]
}
}
}

query_string

可以在查询里边使用AND或者OR来完成复杂的查询,例如:

GET /ops-coffee-2019.05.15/_search
{
"query":{
"query_string": {
"query":"(a.ops-coffee.cn) OR (b.ops-coffee.cn)",
"fields":["host"]
}
}
}

以上表示查找host为a.ops-coffee.cn或者b.ops-coffee.cn的所有记录

也可以用下边这种方式组合更多的条件完成更复杂的查询请求

GET /ops-coffee-2019.05.14/_search
{
"query":{
"query_string": {
"query":"host:a.ops-coffee.cn OR (host:b.ops-coffee.cn AND status:403)"
}
}
}

以上表示查询(host为a.ops-coffee.cn)或者是(host为b.ops-coffee.cn且status为403)的所有记录

与其像类似的还有个simple_query_string的关键字,可以将query_string中的AND或OR用+|这样的符号替换掉

term

term可以用来精确匹配,精确匹配的值可以是数字、时间、布尔值或者是设置了not_analyzed不分词的字符串

GET /ops-coffee-2019.05.14/_search
{
"query":{
"term": {
"status": {
"value": 404
}
}
}
}

term对输入的文本不进行分析,直接精确匹配输出结果,如果要同时匹配多个值可以使用terms

GET /ops-coffee-2019.05.14/_search
{
"query": {
"terms": {
"status":[403,404]
}
}
}

range

range用来查询落在指定区间内的数字或者时间

GET /ops-coffee-2019.05.14/_search
{
"query": {
"range":{
"status":{
"gte": 400,
"lte": 599
}
}
}
}

以上表示搜索所有状态为400到599之间的数据,这里的操作符主要有四个gt大于,gte大于等于,lt小于,lte小于等于

当使用日期作为范围查询时,我们需要注意下日期的格式,官方支持的日期格式主要有两种

  1. 时间戳,注意是毫秒粒度
GET /ops-coffee-2019.05.14/_search
{
"query": {
"range": {
"@timestamp": {
"gte": 1557676800000,
"lte": 1557680400000,
"format":"epoch_millis"
}
}
}
}
  1. 日期字符串
GET /ops-coffee-2019.05.14/_search
{
"query": {
"range":{
"@timestamp":{
"gte": "2019-05-13 18:30:00",
"lte": "2019-05-14",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd",
"time_zone": "+08:00"
}
}
}
}

通常更推荐用这种日期字符串的方式,看起来比较清晰,日期格式可以按照自己的习惯输入,只需要format字段指定匹配的格式,如果格式有多个就用||分开,像例子中那样,不过我更推荐用同样的日期格式

如果日期中缺少年月日这些内容,那么缺少的部分会用unix的开始时间(即1970年1月1日)填充,当你将"format":"dd"指定为格式时,那么"gte":10将被转换成1970-01-10T00:00:00.000Z

elasticsearch中默认使用的是UTC时间,所以我们在使用时要通过time_zone来设置好时区,以免出错

组合查询

通常我们可能需要将很多个条件组合在一起查出最后的结果,这个时候就需要使用ES提供的bool来实现了

例如我们要查询hostops-coffee.cnhttp_x_forworded_for111.18.78.128status不为200的所有数据就可以使用下边的语句

GET /ops-coffee-2019.05.14/_search
{
"query":{
"bool": {
"filter": [
{"match": {
"host": "ops-coffee.cn"
}},
{"match": {
"http_x_forwarded_for": "111.18.78.128"
}}
],
"must_not": {
"match": {
"status": 200
}
}
}
}
}

主要有四个关键字来组合查询之间的关系,分别为:

must: 类似于SQL中的AND,必须包含

must_not: 类似于SQL中的NOT,必须不包含

should: 满足这些条件中的任何条件都会增加评分_score,不满足也不影响,should只会影响查询结果的_score值,并不会影响结果的内容

filter: 与must相似,但不会对结果进行相关性评分_score,大多数情况下我们对于日志的需求都无相关性的要求,所以建议查询的过程中多用filter

写在最后

ES的查询博大精深,本篇文章属于基础入门,内容来源于官网

网上关于ELK搭建部署日志收集的文章很多,但收集到日志之后该如何应用这个数据宝库呢?网上仅有一些大厂分享的比较泛的概念没有实际落地的过程,我在想把这些数据利用起来,初步想法是去ES搜索出来业务或者功能的流量数据,然后做趋势分析,这不从DSL开始学习,欢迎大家加我好友找我交流,我会非常乐意


相关文章推荐阅读:

Elasticsearch Query DSL查询入门的更多相关文章

  1. Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述

    目录 引言 概要 Query and filter context Match All Query 全文查询 Full text queries 小结 参考文档 引言 虽然之前做过 elasticse ...

  2. Elasticsearch Query DSL

    Elasticsearch Query DSL By:授客 QQ:1033553122 1. match_all 1 2. match 2 3. match_phrase 5 4. match_phr ...

  3. Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了

    目录 引言 构建示例 match operator 参数 analyzer lenient 参数 Fuzziness fuzzniess 参数 什么是模糊搜索? Levenshtein Edit Di ...

  4. Elasticsearch Query DSL(查询语言)

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  5. Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query

    目录 引言 Match Phase Query slop 参数 analyzer 参数 zero terms query Match Phrase 前缀查询 max_expansions 小结 参考文 ...

  6. Elasticsearch Query DSL备忘(1)(Constant score query和Bool Query)

    Query DSL (Domain Specific Language),基于json的查询方式 1.Constant score query,常量分值查询,目的就是返回指定的score,一般都结合f ...

  7. Elasticsearch Query DSL 语言介绍

    目录 0. 引言 1. 组合查询 2. 全文搜索 2.1 Match 2.2 Match Phase 2.3 Multi Match 2.4 Query String 2.5 Simple Query ...

  8. elasticsearch的dsl查询

    测试es的dsl查询,准备数据,在插入数据的时候,如果index.type.mapping都没有,es会自动创建 一.数据的准备 curl -XPOST "http://192.168.99 ...

  9. Elasticsearch Query DSL 整理总结(四)—— Multi Match Query

    目录 引言 概要 fields 字段 通配符 提升字段权重 multi_match查询的类型 best_fields 类型 dis_max 分离最大化查询 best_fields 维权使者 tie_b ...

随机推荐

  1. mybatis 运算符转义收录

    在ibatis配置文件写SQL语句的时候对于一些比如“<”,">","<>","&"," ' &q ...

  2. SAP 已经有17个模块

    SAP模块清单: 传统五大郎: MM,SD,PP,FI 财务会计CO 管理会计 +QM 质量管理 (制造业用的不少)+ABAP.BASIS.BW BI商务智能的组件之一CRM 客户管理SRM 供应商管 ...

  3. Java中的迭代迭代器Iterator与枚举器Enumeration

    Iterator 和 Enumeration区别 Iterator 和 Eumberation都是Collection集合的遍历接口,我们先看下他们的源码接口 package java.util; p ...

  4. python的类型

    弱类型是可以自由转换的,如js,字符串和数字能相加 强类型不能自由转换,如python,要加上函数转成相同的类型

  5. Win8+VS2012 配置OpenGL SuperBible5 环境

    (1)glew: 版本:1.7.0-win32 下载地址:https://sourceforge.net/projects/glew/files/glew/ 安装步骤: 将include文件夹下的.h ...

  6. IOS 长姿势---双击Home键

    这不值得大惊小怪,因为按两次Home键后,苹果只是简单第提供了一个历史任务列表,而不是人们以为的当前任务列表——这在苹果网站上已经说得很清楚了.至于为什么苹果没有能力为用户提供一个“任务管理器”,我们 ...

  7. IOS 工程所支持的版本 设置

    如何设置 Base SDK 和 iOS Deployment Target ? http://leopard168.blog.163.com/blog/static/16847184420116159 ...

  8. python读取文件后切片

    from itertools import islice with open(“1.txt") as f: for a in islice(f,0,2): print(a)

  9. Android USB 开发详解

    Android USB 开发详解 先附上 Android USB 官方文档 Android通过两种模式支持各种 USB 外设和 Android USB 附件(实现Android附件协议的硬件):USB ...

  10. 五年java工作应具备的技能

    具有一到五年开发经验 需要学习内容很多 JVM/分布式/高并发/性能优化/Spring MVC/Spring Boot/Spring Cloud/MyBatis/Netty源码分析等等等 01.透彻理 ...