本篇为学习DSL时作的笔记,适合ES新手,大佬请略过~nginx
Query DSL又叫查询表达式,是一种很是灵活又富有表现力的查询语言,采用JSON接口的方式实现丰富的查询,并使你的查询语句更灵活、更精确、更易读且易调试数组
Elasticsearch(如下简称ES)中的数据检索分为两种状况:查询和过滤。缓存
Query查询会对检索结果进行评分,注重的点是匹配程度,例如检索“运维咖啡吧”与文档的标题有多匹配,计算的是查询与文档的相关程度,计算完成以后会算出一个评分,记录在_score
字段中,并最终按照_score
字段来对全部检索到的文档进行排序bash
Filter过滤不会对检索结果进行评分,注重的点是是否匹配,例如检索“运维咖啡吧”是否匹配文档的标题,结果只有匹配或者不匹配,由于只是对结果进行简单的匹配,因此计算起来也很是快,而且过滤的结果会被缓存到内存中,性能要比Query查询高不少app
一个最简单的DSL查询表达式以下:运维
GET /_search
{
"query":{
"match_all": {}
}
}
复制代码
/_search 查找整个ES中全部索引的内容elasticsearch
query 为查询关键字,相似的还有aggs
为聚合关键字性能
match_all 匹配全部的文档,也能够写match_none
不匹配任何文档学习
返回结果:url
{
"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中能够经过如下几种方法来指定索引
ops-coffee-nginx-2019.05.15
为索引名字GET /ops-coffee-nginx-2019.05.15/_search
复制代码
以上表示在ops-coffee-nginx-2019.05.15
索引下查找数据
GET /ops-coffee-nginx-2019.05.15,ops-coffee-nginx-2019.05.14/_search
复制代码
GET /ops-coffee-nginx-*/_search
复制代码
固然这里也能够用逗号分割多个匹配索引
上边有说到查询结果hits
默认只展现10个文档,那咱们如何查询10个之后的文档呢?ES中给了size
和from
两个参数
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中还有如下几个
最简单的查询,下边的例子就表示查找host
为ops-coffee.cn
的全部记录
GET /ops-coffee-2019.05.15/_search
{
"query":{
"match": {
"host":"ops-coffee.cn"
}
}
}
复制代码
在多个字段上执行相同的match查询,下边的例子就表示查询host
或http_referer
字段中包含ops-coffee.cn
的记录
GET /ops-coffee-2019.05.15/_search
{
"query":{
"multi_match": {
"query":"ops-coffee.cn",
"fields":["host","http_referer"]
}
}
}
复制代码
能够在查询里边使用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能够用来精确匹配,精确匹配的值能够是数字、时间、布尔值或者是设置了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用来查询落在指定区间内的数字或者时间
GET /ops-coffee-2019.05.14/_search
{
"query": {
"range":{
"status":{
"gte": 400,
"lte": 599
}
}
}
}
复制代码
以上表示搜索全部状态为400到599之间的数据,这里的操做符主要有四个gt
大于,gte
大于等于,lt
小于,lte
小于等于
当使用日期做为范围查询时,咱们须要注意下日期的格式,官方支持的日期格式主要有两种
GET /ops-coffee-2019.05.14/_search
{
"query": {
"range": {
"@timestamp": {
"gte": 1557676800000,
"lte": 1557680400000,
"format":"epoch_millis"
}
}
}
}
复制代码
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
来实现了
例如咱们要查询host
为ops-coffee.cn
且http_x_forworded_for
为111.18.78.128
且status
不为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开始学习,欢迎你们加我好友找我交流,我会很是乐意
相关文章推荐阅读: