ElasticSearch查询语句归类
背景:初学者面对ES的DSL(domain specific language)查询显得一脸懵逼,看着各种嵌套的语句不知道有什么规律,下面就给大家总结一下,方便学习理解记忆。官方的文档版本好像是2.X,ES更新很快现在都7.X,现在的很多语法和关键字都和2.x的版本不同了,甚至删除了不少关键字,随着版本越高,相应的查询语法和关键字等方方面面也逐渐稳定起来了。这里我是按照7.X版本总结的。
根下面的关键字
- query:代表查询,搜索 类似于SQL的select关键字
- aggs:代表聚合,类似于SQL的group by 关键字,对查询出来的数据进行聚合 求平均值最大值等
- highlight:对搜索出来的结果中的指定字段进行高亮显示,搜索“中华人民共和国万岁”,结果里面符合搜索关键字 全部是红色的高亮显示。
- sort: 指定字段对查询结果进行排序显示,类比SQL的order by关键字
- from和*size: 对查询结果分页,类似于SQL的limit关键字
- post_filter:后置过滤器,在聚合查询结果之后,再对查询结果进行过滤。
query:叶子查询
ES是的核心是根据字段进行倒排索引,在进行倒排索引的时候和该字段的type有关系,如下:
"mappings": {
"properties": {
"age": {
"type": "long"
},
"country": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
上面的map字段定义中country的type是keyword(大小限制是32K),
那么根据这个字段进行倒排索引的时候,你存储的值是什么就是什么,
比如存储的数据的country字段是America,那么默认创建倒排索引的时候就会是America。
而字段name的type是text, 进行倒排索引的时候,你存储的值都会被转换成全小写进行
存储,对这个字段的内容进行分词, 比如存储的数据的name字段是Rain,
那么在该字段的倒排索引的内容就会是rain,默认转换成小写。
ES的查询原则:拿我们查询的字段去倒排索引上查询匹配
- match:全局查询,如果是多个词语,会进行分词查询。字母字母默认转换成全小写,进行匹配。
{
"query":{
"match":{
"name":"比尔盖茨"
}
}
}
- match_phrase:查询短语,会对短语进行分词,match_phrase的分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的
{
"query":{
"match_phrase":{
"country":"中 国"
}
}
}
- term: 单个词语查询,会精确匹配词语,会根据输入字段精确匹配。
{
"query":{
"term":{
"country":"America"
}
}
}
- terms:多个词语查询,精确匹配,满足多个词语中的任何一个都会返回。
{
"query":{
"terms":{
"country":["America","america"]
}
}
}
- exists:类似于SQL的ISNULL,字段不为空的会返回出来。
{
"query":{
"exists":{
"field":"country"
}
}
}
- range: 类似于SQL的between and关键字,返回查询
{
"query":{
"range":{
"age":{
"lte":50,
"gte":20
}
}
}
}
- ids:一次查询多个id,批量返回。
{
"query":{
"ids":{
"values":["JJpNJHgBLLjdyTtc34ag","JZp5JHgBLLjdyTtcEobD"]
}
}
}
- fuzzy:模糊查询
编辑距离:就是一个词语变成另外一个词语要编辑的次数,也叫莱文斯坦距离(Levenshtein distance),指两个字符串之间,由一个转成另一个所需的最少编辑操作次数,包括
将一个字符替换成另一个字符
插入一个字符
删除一个字符
Damerau–Levenshtein distance是莱温斯坦距离的拓展版本,将相邻位置的两个字符的互换当做一次编辑,而在经典的莱文斯坦距离计算中位置互换是2次编辑。
{
"query":{
"fuzzy":{
"name":{
"value":"fain",
"fuzziness": 1, // 允许的编辑距离 (match也能配合这个设置)
"prefix_length": 0, // 前多少个字符要保持一致 (match也能配合这个设置)
"max_expansions": 50, // (match也能配合这个设置)
"transpositions": true // true:莱温斯坦距离拓展版,false:经典莱温斯坦距离(match也能配合这个设置)
}
}
}
}
query:复合查询
为什么是复合查询,因为可以嵌套查询,不像叶子查询那样,是最底层的查询。
复合查询其他的关键字就不多解释了,着重介绍一下bool查询,bool查询下面四个查询语句
都是内嵌叶子查询的,且他们有个共同特性,就是查询条件只有是否。
- must:返回的文档必须满足must子句的条件,并且参与计算分值.
- must_ not:返回的文档必须不满足must_not定义的条件
- should:返回的文档可能满足should子句的条件。在一个Bool查询中,如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回。minimum_should_match参数定义了至少满足几个子句
- filter:返回的文档必须满足filter子句的条件。不会参与计算分值,如果一个查询既有filter又有should,那么至少包含一个should子句,Filter过滤的结果会进行缓存,查询效率更高,建议使用filter。