ES查询语法
Query_string
1. Query_string
1.1 Query_string (不常用)
参数拼接到查询路劲中查询,查询可以不指定 type 的类型
//查询所有, logstash-bus*查找所有索引, 相当于数据库, 路劲还可以加类型, 相当于表名
GET /logstash-bus*/_search
//查询className=PrincipalAccountingImpl的
GET /logstash-bus*/_search?q=className:PrincipalAccountingImpl
1.2 查询结果
查询结果部分字段说明:
-
took
:耗费了几毫秒。 -
timed_out
:是否超时,这里是没有。
*_shards
:数据拆成了若干个分片,所以对于搜索请求,会打到所有primary shard
(或者是它的某个replica shard
也可以)。 -
hits.total
:查询结果的数量,3个document。 -
hits.max_score
:score的含义,就是document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高。 -
hits.hits
:包含了匹配搜索的document的详细数据。 -
aggregations
: 聚合查询的结果
DSL查询语法
2.DSL查询语法
2.1 Query
query_String
查询在复杂查询时很那用, DSL使用json的方式进行查询, 一般查询都是使用get方式(post也是可以请求到的, 但是不符合Restful规范), es的get查询支持请求体
2.1.1 查询所有
GET /logstash-bus*/_search
{
"query": {
"match_all": {
}
}
}
2.1.2 查询指定条件
//match中的字段值会被分词, 含有其中一个分词的就会被检索
GET /logstash-bus*/_search
{
"query": {
"match": {
"className": "PrincipalAccountingImpl"
}
}
}
2.1.3 排序查询
{
"query": {
"match": {
"className": "PrincipalAccountingImpl"
}
}
, "sort": [
{
"port": {
"order": "asc"
}
}
]
}
2.1.4 term不分词查询
value值部分会作为整体被查询, 不会被分词, 与match做区分, match的value是会被分词作匹配查询的.
{
"query": {
"term": {
"reqParam": {
"value": "VAPrincipalBalNormalAccountingImpl handleLUE"
}
}
}
}
2.1.5 match_phrase
//methodName中 "这个", "测试", "短语" 会做精准匹配, 都全部含有这三个短语的文档才会被检索出来
"query": {
"match_phrase": {
"methodName": "这个测试短语"
}
}
2.1.6 bool多条件复合查询
bool查询的使用:
Bool查询对应Lucene中的BooleanQuery,它由一个或者多个子句组成,每个子句都有特定的类型。
1.must
返回的文档必须满足must子句的条件,并且参与计算分值
2.filter
返回的文档必须满足filter子句的条件。但是不会像Must一样,参与计算分值
3.should
返回的文档可能满足should子句的条件。在一个Bool查询中,如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回。minimum_should_match参数定义了至少满足几个子句, 默认情况是1
4.must_not
返回的文档必须不满足must_not定义的条件。
如果一个查询既有filter又有should,那么至少包含一个should子句。
bool查询也支持禁用协同计分选项disable_coord。一般计算分值的因素取决于所有的查询条件。
bool查询也是采用more_matches_is_better的机制,因此满足must和should子句的文档将会合并起来计算分值。
2.2 _source元数据查询
使用_source
可以只查询需要展示的列, 相当于sql
的select offset,methodName from ...
GET /logstash-bus*/_search
{
"_source": [
"offset",
"methodName"]
}
2.3 分页查询
from表示从第几行开始,size表示查询多少条文档。from默认为0,size默认为10,
如
//从第二页开始, 每页20条
{"size": 20
, "from": 2
}
2.4 aggs聚合查询
聚合查询的结构:
"aggs" : {
"" : { //聚合的名字
"" : { //聚合的类型
//聚合体:对哪些字段进行聚合
}
[,"aggs" : { []+ } ]? //在聚合里面在定义子聚合, 一些聚合查询支持子聚合
}
[,"" : { ... } ]* //聚合的名字
}
举例说明:
"aggs": {
"avg_useTime": { //聚合的名字
"terms": { //聚合类型是桶聚合terms方式
"field": "bussEventId.keyword" //聚合字段是bussEventId.keyword
},
"aggs": { //桶聚合支持子聚合, 这是子聚合的方式
"avg_useTime": { //子聚合的名字
"avg": { //子聚合的聚合类型
"field": "useTime" //子聚合的字段
},
}
}
}
}
聚合分类: 指标聚合, 桶聚合, 矩阵聚合, 管道聚合
2.4.1 指标聚合
比如求所有文档某个字段求最大、最小、和、平均值, 可以对某个field进行计算.
1.max ,min, avg, sum
以avg为例, 计算offset在所有文档中的均值
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
},
{
"match": {
"maiDianType": "request_execute"
}
}
]
}
},
"_source": ["prodSubNo","useTime","channelInto","maiDianType","bussEventId"],
"aggs": {
"useTime": {
"avg": { // 聚合结果是offset字段的平均值
"field": "offset"
}
}
},
"size": 1
}
运行结果:
2. value_count值统计
该聚合一般域其它 single-value 聚合联合使用,比如在计算一个字段的平均值的时候,可能还会关注这个平均值是由多少个值计算而来。
例子:统计搜索结果中maiDianType字段出现的次数
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
}
]
}
},
"_source": ["prodSubNo","useTime","channelInto","maiDianType","bussEventId"],
"aggs": {
"offset": {
"value_count": {
"field": "maiDianType.keyword"
}
}
},
"size": 1
}
搜索结果:
3. Cardinality聚合(相当于distinct)
基于文档的某个值(可以是特定的字段,也可以通过脚本计算而来),计算文档非重复的个数(去重计数),相当于sql中的distinct。
例子: 统计搜索结果中maiDianType出现的种类
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
}
]
}
},
"_source": ["prodSubNo","useTime","channelInto","maiDianType","bussEventId"],
"aggs": {
"maiDianType_count": {
"cardinality": {
"field": "maiDianType.keyword"
}
}
},
"size": 1
}
搜索结果: maiDianType共有6种值
4. stats统计聚合
基于文档的某个值(可以是特定的数值型字段,也可以通过脚本计算而来),计算出一些统计信息(min、max、sum、count、avg5个值)。
例子: 基于useTime进行值统计
ps: 这个例子中是基于脚本进行的统计
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
},
{
"match": {
"maiDianType": "request_execute"
}
}
]
}
},
"_source": [
"prodSubNo",
"useTime",
"channelInto",
"maiDianType",
"bussEventId"
],
"aggs": {
"useTime": {
"stats": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
}
}
}
},
"size": 1
}
统计结果:
5. extended_stats拓展的统计聚合
与stats功能相似, 比stats多4个统计结果: 平方和、方差、标准差、平均值加/减两个标准差的区间
例子:
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
},
{
"match": {
"maiDianType": "request_execute"
}
}
]
}
},
"_source": [
"prodSubNo",
"useTime",
"channelInto",
"maiDianType",
"bussEventId"
],
"aggs": {
"useTime": {
"extended_stats": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
}
}
}
},
"size": 1
}
结果:
6. Percentiles百分比聚合
对指定字段(脚本)的值按从小到大累计每个值对应的文档数的占比(占所有命中文档数的百分比),返回指定占比比例对应的值。默认返回[ 1, 5, 25, 50, 75, 95, 99 ]分位上的值,也可以指定分位置.
例子:
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
},
{
"match": {
"maiDianType": "request_execute" }
}
]
}
},
"_source": ["prodSubNo","useTime","channelInto","maiDianType","bussEventId"],
"aggs": {
"useTime_percentiles": {
"percentiles": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
}
}
}
},
"size": 1
}
结果:
ps:
"1.0":30 代表: useTime<30的, 占比1%
"99.0":237 代表: useTime<237的, 占比99%
例子: 指定聚合的百分比
"percentiles": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
},
"percents": [
50,
75,
95,
99
]
}
查询结果:
2.4.2 桶聚合
1.terms聚合
词聚合。基于某个field,该 field 内的每一个【唯一词元】为一个桶,每个桶内可以做再次聚合.
列子: 以prodSubNo的每个值作为聚合, 聚合结果默认排序为从大到小
GET /logstash-bus*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"prodSubNo": "601001"
}
}
]
}
},
"_source": [
"prodSubNo",
"useTime",
"channelInto",
"maiDianType",
"bussEventId"
],
"aggs": {
"useTime": {
"terms": {
"field": "prodSubNo"
}
}
},
"size": 1
}
搜索结果:
doc_count_error_upper_bound:
//文档计数的最大偏差值
sum_other_doc_count:
, //未返回的其他项的文档数
列子: 以prodSubNo的每个值作为聚合, 得到的桶继续做avg子聚合, 得到每个prodSubNo下的useTime的avg聚合结果
GET /logstash-bus*/_search
{
"_source": [
"prodSubNo",
"useTime",
"channelInto",
"maiDianType",
"bussEventId"
],
"aggs": {
"useTime": {
"terms": {
"field": "prodSubNo"
},
"aggs": {
"avg_useTime": {
"stats": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
}
}
}
}
}
},
"size": 1
}
搜索结果:
2. filter过滤聚合
基于一个条件,来对当前的文档进行过滤的聚合。
例子: 对查询结果进行过滤, prodSubNo=601001聚合过滤, 可对过滤后的内容进行子聚合查询, 这里使用stats统计聚合
GET /logstash-bus*/_search
{
"aggs": {
"useTime": {
"filter": {
"match": {
"prodSubNo": "601001"
}
},
"aggs": {
"useTime_avg": {
"stats": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
}
}
}
}
}
}
}
查询结果:
过滤聚合与query+aggs最终得到的聚合结果一样, 但是先query结果直接就是完全符合过滤条件的
3.filters 多过滤聚合
基于多个过滤条件,来对当前文档进行【过滤】的聚合,每个过滤都包含所有满足它的文档(多个bucket中可能重复),先过滤再聚合。
例子: 使用prodSubNo=601001和maiDianType=script分别对索引结果进行过滤
GET /logstash-bus*/_search
{
"_source": [
"prodSubNo",
"useTime",
"channelInto",
"maiDianType",
"bussEventId"
],
"aggs": {
"useTime": {
"filters": {
"filters": {
"prod": {
"match": {
"prodSubNo": "601001"
}
},
"maiDianType":{
"match":{
"maiDianType":"script"
}
}
}
}
}
},
"size": 1
}
搜索结果:
4. range范围聚合
范围分组聚合。基于某个值(可以是 field 或 script),以【字段范围】来桶分聚合。范围聚合包括 from 值,不包括 to 值(区间前闭后开)。
例子: 对于useTime字段值进行0-20和20-40范围内的聚合
ps: 对范围聚合后的结果,还可以进行子聚合
GET /logstash-bus*/_search
{
"_source": [
"prodSubNo",
"useTime",
"channelInto",
"maiDianType",
"bussEventId"
],
"aggs": {
"小于20": {
"range": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
},
"ranges": [
{
"from": 0,
"to": 20
}
]
}
},
"20-40": {
"range": {
"script": {
"lang": "painless",
"source": "if(!doc.containsKey('useTime')) return -1; return Long.parseLong(doc['useTime'].value != null ? doc['useTime'].value:'-2')"
},
"ranges": [
{
"from": 20,
"to": 40
}
]
}
}
},
"size": 1
}
搜索结果: