Py学习  »  Elasticsearch

ElasticSearch的查询语法很另类?学会归类so easy!

架构师 • 1 年前 • 182 次点击  
架构师(JiaGouX)
我们都是架构师!
架构未来,你来不来?


因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享

背景

初学者面对ES的DSL(domain specific language)查询显得一脸懵逼,看着各种嵌套的语句不知道有什么规律,下面就给大家总结一下,方便学习理解记忆。

官方的文档版本好像是2.X,ES更新很快现在都7.X,现在的很多语法和关键字都和2.x的版本不同了,甚至删除了不少关键字,随着版本越高,相应的查询语法和关键字等方方面面也逐渐稳定起来了。这里我是按照7.X版本总结的。

ES搜索语法架构


根下面的关键字


  • 「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。

如喜欢本文,请点击右上角,把文章分享到朋友圈
如有想了解学习的技术点,请留言给若飞安排分享

·END·

相关阅读:


作者:今天例外

来源:https://blog.csdn.net/qq_15022971/article/details/114630565

版权申明:内容来源网络,仅供分享学习,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

架构师

我们都是架构师!



关注架构师(JiaGouX),添加“星标”

获取每天技术干货,一起成为牛逼架构师

技术群请加若飞:1321113940 进架构师群

投稿、合作、版权等邮箱:admin@137x.com

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/150644
 
182 次点击