ElasticSearch 查询语言 DSL

在 elasticSearch 中,共有两种查询:1. url 搜索 2. DSL查询语言

  • url 搜索

    顾名思义, url搜索的参数都通过url来传递,方便来进行一般的数据查看,大概如下面这种形式的

        GET twitter/_search?q=user:kimchy
    
  • Request Body 搜索

    通过的 DSL(Domain Specific Language) 来定义查询语言, 像下面这个

        GET /_search
        {
        "query": { 
            "bool": { 
            "must": [
                { "match": { "title":   "Search"        }}, 
                { "match": { "content": "Elasticsearch" }}  
            ],
            "filter": [ 
                { "term":  { "status": "published" }}, 
                { "range": { "publish_date": { "gte": "2015-01-01" }}} 
            ]
            }
        }
        }
    

这篇文章主要来说明 DSL 查询的原理和语法。

DSL 搜索查询

Elasticsearch提供了基于JSON的完整查询DSL(Domain Specific Language[特定于域的语言])来定义查询。将查询DSL视为查询的AST(Abstract Syntax Tree[抽象语法树]。

它由两种子句组成:

  • 子句查询条件

    子句查询在特定字段中查找特定值,例如match,term或range查询。这些查询可以单独使用。

  • 复合查询条件

    复合查询是把 子句查询和 其他复合查询组合起来,实现复杂逻辑的查询。例如bool和 dis_max 查询

相同的查询条件的结果依赖于他们的上下文环境,elasticSearch 的DSL 主要提供两种上下文环境 : query[查询上下文] 和 filter[过滤器上下文]。

filter 和 query 上下文

注意了, DLS关键是要搞清楚 filter 和 query 的差别

  • 相关性得分 [relevance score]

默认情况下, ElaticSearch通过相关性得分(查询和文档的匹配程度)来对结果排序。
相关性得分是一个正浮点数,在_search API 中以 _score 字段返回。_score 值越大,相关性越高。
每种字段以不同的方式计算_score, _score的计算也根据查询条件运行于 filter 或者 query 而不同。

  • 结构化查询

在 query 上下文中, 一个查询条件主要解决的问题是: 条件和文档的匹配程度有多高。除了解决匹配度的问题, 还会计算一个相关性程度,作为元数据 _score 返回。

  • 结构化过滤

在 filter 上下文中, 一个查询条件主要解决的问题是: 条件和文档是否匹配。通常结果是匹配和不匹配,这主要用于过滤结构化数据。

一条过滤语句会询问每个文档的字段值是否包含着特定值:

  1. status 字段中是为 "published" ?
  2. created 的日期范围是否在 2013 到 2014 ?

不论是把查询条件传递给 bool下的 filter 或者 must 参数等, 还是在 聚合中的filter, filter都会起作用

  • 性能差异
    使用过滤语句得到的结果集 -- 一个简单的文档列表,快速匹配运算并存入内存是十分方便的, 每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的。

查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。

幸亏有了倒排索引,一个只匹配少量文档的简单查询语句在百万级文档中的查询效率会与一条经过缓存 的过滤语句旗鼓相当,甚至略占上风。 但是一般情况下,一条经过缓存的过滤查询要远胜一条查询语句的执行效率。

过滤语句的目的就是缩小匹配的文档结果集,所以需要仔细检查过滤条件。

  • 什么情况下使用
    原则上来说,使用查询语句做全文本搜索或其他需要进行相关性评分的时候,剩下的全部用过滤语句
    Use query clauses in query context for conditions which should affect the score of matching documents (i.e. how well does the document match), and use all other query clauses in filter context.

复合查询

  • bool

    组合其他查询的默认查询: 如must, should, must_not, or filter

    must 和 should 会把score 合并起来, 越匹配越好

    must_not 和 filter 则在filter 条件中执行

  • booting query

    增加正匹配查询的匹配分数, 减少负匹配的查询分数。

  • constant_score query

    包含另一个查询的查询, 但是所有文档使用同一score, 在过滤器上下文执行

全文搜索查询

  • common terms query

    大概可以理解为优先级查询, 比如 not happy, 会优先查询含有 happy的文档

    忽略或者从结构中去过滤一些高频率词的查询匹配,通常如 the, a, not 等副词,来提高搜索效率 ,这些词通常单独没有意义,组合起来又不可缺少, 例如 happy 和 not happy, common 首先搜索happy,得到的结果中过滤 在对not happy 计算_score.

  • intervals query

    intervals query 允许用户精确控制查询词在文档中出现的先后关系,实现了对terms顺序、terms之间的距离以及它们之间的包含关系的灵活控制

    这个查询匹配 my_text 中" my favorite food is cold porridge.", 但是不会匹配 "it's cold my favorite food is porridge."

    POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "all_of" : {
          "ordered" : true,
          "intervals" : [
            {
              "match" : {
                "query" : "my favorite food",
                "max_gaps" : 0,
                "ordered" : true
              }
            },
            {
              "any_of" : {
                "intervals" : [
                  { "match" : { "query" : "hot water" } },
                  { "match" : { "query" : "cold porridge" } }
                ]
              }
            }
          ]
        }
      }
    }
  }
}
  • match

    匹配文本,数字,日期或布尔值等文档,在执行文本匹配之前,首先会 分析查询词汇。
    match是full-text搜索的默认查询,包含模糊查询。

    match 的语法结构:

    {
        "query":{
            "match": {
                <field_name>: {     // field_name 是match 的 top-level 参数
                    "query" : ""     // 查询内容
                    "analyzer":   "" // 分词器
                    "operator" "OR[默认], AND" //用于解释 query中的bool逻辑
                    ..... 
                }
            }
        }
    }
  • match phrase query

    短语查询, 查询条件按照一个词来处理

    例如: "He is" 只能查询到"He is a student", 而不能查询到 "He said that is a monstor."

-match phrase prefix query

短语前缀查询, 查询文本的最后一项是单词的前缀

```
    GET /_search
    {
        "query": {
            "match_phrase_prefix" : {
                "message" : {
                    "query" : "quick brown f"
                }
            }
        }
    }

```
  • multi match query

    match 的扩展, 可以规定多个字符串匹配.
    语法结构和 match 稍有不同


GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "first_name", "last_name" ],      // field 可以是很多个
      "operator":   "and" 
    }
  }
}


term-level 查询

查询结构化数据中的精确值, term-level 不对搜索文本进行分析, 它匹配精确的值。

  • exists

  • fuzzy

    自动模糊查询

  • ids

        GET /_search
    {
        "query": {
            "ids" : {
                "values" : ["1", "4", "100"]
            }
        }
    }
  • preix
GET /_search
{
    "query": {
        "prefix": {
            "user": {
                "value": "ki"
            }
        }
    }
}

  • range

GET _search
{
    "query": {
        "range" : {
            "age" : {
                "gte" : 10,
                "lte" : 20,
                "boost" : 2.0
            }
        }
    }
}


  • regexp

  • term

    返回在特定字段中内容完全相同的文档。

    可以term去找一个有精确值字段【价格,productID或用户名】的文档。

    避免在类型为text字段上使用term, 要使用请使用 match。 elasticSearch 会对text字段使用analysis, 这会导致term 搜索边的困难

            GET /_search
        {
            "query": {
                "term": {
                    "user": {
                        "value": "Kimchy",
                        "boost": 1.0
                    }
                }
            }
        }
    
  • terms

    terms的多字段形式

  • term_set

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

推荐阅读更多精彩内容