Elasticsearch查询语法
Elasticsearch在很多情况下被当作一个文本型的NOSQL数据库,也有增删查改操作
数据写入
Elasticsearch的一大特点是,全是RESTful接口处理JSON请求1
2
3
4
5# curl -XPOST http://localhost:9200/logstash-2017.10.29/testlog -d '{
"date": "1509271325780"
"user": "jack"
"mesg": "first message into Elasticsearch"
}'
数据获取
在数据写入时,会返回该数据的_id,这是后续用来获取数据的关键:1
2
3
4
5
6
7# curl -XGET http://localhost:9200/logstash-2017.10.29/testlog/AV9nlDQhv96dGKcHC2zo
{"_index": "logstash-2017.10.29","_type": "testlog", "_id": "AV9nlDQhv96dGKcHC2zo", "_version": 1, "found": true, "_source": {
"date": "1509271325780",
"user": "jack",
"mesg": "first message into Elasticsearch"
}
}
也可以使用下面语法来获取源数据部分1
curl -XGET http://localhost:9200/logstash-2017.10.29/testlog/AV9nlDQhv96dGKcHC2zo/_source
或者使用下面语法来指明获取字段1
curl -XGET http://localhost:9200/logstash-2017.10.29/testlog/AV9nlDQhv96dGKcHC2zo?fields=user,mesg
数据删除
1 | #删除单条数据 |
数据更新
分为两种情况:
- 全量提交
- 指明
_id再发送一次写入请求1
2
3
4
5
6#全部提交
# curl -XPOST http://localhost:9200/logstash-2017.10.29/testlog/AV9nlDQhv96dGKcHC2zo -d '{
"date": "1509271325780",
"user": "jack",
"mesg": "first message into Elasticsearch but version 2"
}'或者1
2
3
4
5
6#局部提交
# curl -XPOST http://localhost:9200/logstash-2017.10.29/testlog/AV9nlDQhv96dGKcHC2zo -d '{
"doc": {
"user": "jack wang"
}
}'1
2
3# curl -XPOST http://localhost:9200/logstash-2017.10.29/testlog/AV9nlDQhv96dGKcHC2zo/_update -d '{
"scripts": "ctx._source.user = \"someone\""
}'
全文搜索
1 | # curl -XGET http://localhost:9200/logstash-2017.10.29/testlog/_search?pretty=true?q='first' |
querystring 语法
上例中?q=后面的就是querystring语法,会在kibana中经常使用
全文检索:直接写搜索的单词。如:?q=aaaa单字段的全文检索:在搜索单词之前加上字段名和冒号。如:?q=user:jack单字段的精确检索:在搜索单词前加上双引号。如:?q=user:"jack"多个检索条件的组合:可以使用NOT、AND、OR来组合检索,必须是大写的。如:?q=user:("jack" OR "bob") AND NOT mesg:aaaa字段是否存在:_exists_:user表示要求user字段存在,_missing_:user表示user字段不存在。如:?q=_exists_:beat.name通配符:用?表示单字母,*表示任意个字母。如:?q=DevE?N,?q=DevE?N*正则:比通配符更复杂一点点。如:?q=/dub{2}o/
注:Elasticsearch正则性能不好,尽量不要使用太复杂或不使用。参考Elasticsearch正则表达式语法近似搜索:用~表示搜索单词可能有一字母写的不对。如:?q=dubao~范围搜索:对数值和时间。如:?q=@timestamp:>150928968615,?q=@timestamp:["now-1m" TO "now"]
DSL语法
Elasticsearch也支持其他查询语法,具体见:Elasticsearch其他查询语法
term query1
2
3
4
5
6
7
8# curl -XGET http://localhost:9200/_search -d '
{
"query": {
"term": {
"_id": "AV9orWWLv96dGKcHDVyi"
}
}
}'
聚合请求
在检索范围确定后,Elasticsearch还执行对结果集做聚合查询,返回更直接的聚合统计结果。aggression分为bucket和metric,分别用作词元划分和数值计算。而bucket aggression还支持在自身结果集的基础上叠加新的aggression。
实现一个时序的百分比统计1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# curl -XPOST 'http://localhost:9200/logstash-2017.10.29/_search?size=0&pretty' -d '{
"aggs": {
"percentile_over_time": {
"date_histogram": {
"field": "@timestamp",
"interval": "1m"
},
"aggs": {
"percentile_one_time": {
"percentiles": {
"field": "requesttime"
}
}
}
}
}
}'
pipeline聚合
Elasticsearch 2.x 新增pipeline aggression类型,再已有aggression返回的数组数据之后,再对这组数值做一次运算。在Kibana 5.0的timelion中有用到
常见的pipeline聚合场景,就是对时序数据求移动平均值
示例:
对响应时间设置如下:周期为7,移动窗口为30,alpa、beta、gamma参数均为0.5,holt-winters季节性预测2个未来值1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31{
"aggs": {
"my_date_histo": {
"date_histogram": {
"field": "@timestamp",
"interval": "1h"
},
"aggs": {
"avgtime": {
"avg": { "field": "requesttime" }
},
"the_movavg": {
"moving_avg": {
"buckets_path": "avgtime",
"window": 30,
"model": "holt_winters",
"predict": 2,
"settings": {
"type": "mult",
"alpha": 0.5,
"beat": 0.5,
"gamma": 0.5,
"period": 7,
"pad": true
}
}
}
}
}
}
}
buckets_path语法
aggression是有堆叠层级关系的,所以pipeline aggression在引用 metric aggression时会涉及到层级的问题。在上例中,the_movavg和avgtime是同一级,所以buckets_path直接就写avgtime即可。但如果把the_movavg上提一层,跟my_date_histo同级1
"buckets_path": "my_date_histo > avgtime"
如果用的是返回的数值有多个值的聚合,比如?percentiles或者?extended_stats1
"buckets_path": "percentile_over_time > percentile_one_time.95"
目前Elasticsearch支持的聚合请求列表,参考:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-aggregations.html
参考阅读:Holt Winters预测算法,见:https://en.wikipedia.org/wiki/Holt-Winters
搜索请求参数
搜索请求参数如下:
from: 从索引的第几条数据开始返回,默认是0size: 返回多少条数据,默认是10
Elasticsearch集群实际是需要给 coordinate node 返回 shards number x (from + size)条数据,然后在单机上进行排序,最后给客户端返回大小为 size的数据。所以请慎用 from和size参数
此外,Elasticsearch 2.x 还增加了一个索引级别的动态控制配置项:index.max_result_window,默认为10000,即from + size大于10000,Elasticsearch会直接拒绝这次请求不进行具体搜索,以保护节点
Elasticsearch 2.x 还优化了,当设置 “size”:0 时,自动改变 search_type为 count。跳过过程的 fetch 阶段timeout:coordinate node 等待超时时间。当达到阀值后,coordinate node 会直接把当前收到的数据返回个客户端,不再等待 data node后续的返回结果了。
注:这个参数只是为了配合客户端程序,并不能取消data node上搜索任务还在运行和占用资源terminate_after:各data node上,扫描单个分片时找到多少记录后,就认为足够了。这个参数可以切实保护 data node 上搜索任务不会长期运行和占用资源。也就是意味着搜索范围没有覆盖全部索引,是一个抽样数据。准确率不好判断。request_cache:各data node上,在分片级别对请求的响应(仅限于hits.total数值、 aggression 和 suggestion的结果集)做的缓存。注意,这个缓存的键值要求很严格,请求的JSON必须一字不易,缓存才能命中
另外,request_cache 参数不能写在请求的JSON里,只能以URL参数的形式存在,示例如下:1
2
3
4
5
6
7
8
9# curl -XPOST http://localhost:9200/_search?request_cache=true -d '
{
"size": 0,
"timeout": "120s",
"terminate_after": 1000000,
"query": { "match_all": {} },
"aggs": {"terms": { "terms" : { "field" : "keyname" } } }
}
'
本作品采用知识共享署名 2.5 中国大陆许可协议进行许可,欢迎转载,但转载请注明来自Jack Wang Blog,并保持转载后文章内容的完整。本人保留所有版权相关权利。
本文出自”Jack Wang Blog”:http://www.yfshare.vip/2017/10/30/Elasticsearch%E6%9F%A5%E8%AF%A2%E8%AF%AD%E6%B3%95/