ES查询语法

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: 聚合查询的结果
查询结果.png

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可以只查询需要展示的列, 相当于sqlselect offset,methodName from ...

GET /logstash-bus*/_search
{
  "_source": [
    "offset",
    "methodName"]
}
image.png

2.3 分页查询

from表示从第几行开始,size表示查询多少条文档。from默认为0,size默认为10,

//从第二页开始, 每页20条
 {"size": 20
  , "from": 2
  }

2.4 aggs聚合查询

聚合查询的结构:

"aggs" : {
    "<aggregation_name>" : {      //聚合的名字
        "<aggregation_type>" : {     //聚合的类型
            <aggregation_body>      //聚合体:对哪些字段进行聚合
        }
        [,"aggs" : { [<sub_aggregation>]+ } ]?   //在聚合里面在定义子聚合, 一些聚合查询支持子聚合
    }
    [,"<aggregation_name_2>" : { ... } ]*                      //聚合的名字
}

举例说明:

"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
 
}

运行结果:


image.png
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
 
}

搜索结果:


image.png
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种值


image.png
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
}

统计结果:


image.png
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
}

结果:


image.png
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
 
}

结果:


image.png

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
        ]
      }

查询结果:


image.png

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
}

搜索结果:


image.png

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
}

搜索结果:


image.png
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')"
            }
          }
        }
      }
    }
  } 

}

查询结果:


image.png

过滤聚合与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
}

搜索结果:


image.png
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
}

搜索结果:


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352