Elasticsearch查詢和聚合基本語法

1.概述

Elasticsearch主要的查詢語法包括URI查詢和body查詢结洼,URI比較輕便快速僻弹,而body查詢作為一種json的格式化查詢,可以有許多限制條件并炮。本文主要介紹結(jié)構(gòu)化查詢的query默刚,filter,aggregate的使用逃魄,本文使用的ES版本為6.5.4荤西,中文分詞器使用的ik,安裝和使用可以參考:
Elasticsearch 安裝和使用
Elasticsearch中ik分詞器的使用
在ES建立以下索引伍俘,并且導(dǎo)入數(shù)據(jù)

PUT /news
{
        "aliases": {
            "news": {}
        },
        "mappings":{
            "news": {
                "dynamic": "false",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "title": {
                        "analyzer": "ik_max_word",
                        "type": "text"
                    },
                    "summary": {
                        "analyzer": "ik_max_word",
                        "type": "text"
                    },
                    "author": {
                        "type": "keyword"
                    },
                    "publishTime": {
                        "type": "date"
                    },
                    "modifiedTime": {
                        "type": "date"
                    },
                    "createTime": {
                        "type": "date"
                    },
                    "docId": {
                        "type": "keyword"
                    },
                    "voteCount": {
                        "type": "integer"
                    },
                    "replyCount": {
                        "type": "integer"
                    }
                }
            }
        },
        "settings":{
            "index": {
                "refresh_interval": "1s",
                "number_of_shards": 3,
                "max_result_window": "10000000",
                "mapper": {
                    "dynamic": "false"
                },
                "number_of_replicas": 1
                }
                }
            }
        }
    }

2.查詢

2.1 一個查詢的例子

一個簡單的查詢例子如下邪锌,查詢主要分為query和filter,這兩種類型的查詢結(jié)構(gòu)都在query里面癌瘾,剩下的sort標(biāo)識排序觅丰,size和from用來翻頁,_source用來指定召回document返回哪些字段妨退。
查詢請求:

GET /news/_search
{
  "query": {"match_all": {}}, 
  "sort": [
    {
      "publishTime": {
        "order": "desc"
      }
    }
  ],
  "size": 2,
  "from": 0,
  "_source": ["title", "id", "summary"]
}

返回結(jié)果:

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 204,
    "max_score" : null,
    "hits" : [
      {
        "_index" : "news",
        "_type" : "news",
        "_id" : "228",
        "_score" : null,
        "_source" : {
          "summary" : "據(jù)陜西高院消息妇萄,6月11日上午,西安市中級人民法院二審公開開庭宣判了陜西省首例“套路貸”涉黑案件——韓某某等人非法放貸一案咬荷,法院駁回上訴冠句,維持原判。西安市中級人",
          "id" : 228,
          "title" : "陜西首例套路貸涉黑案宣判:團伙對借款人噴辣椒水"
        },
        "sort" : [
          1560245097000
        ]
      },
      {
        "_index" : "news",
        "_type" : "news",
        "_id" : "214",
        "_score" : null,
        "_source" : {
          "summary" : "網(wǎng)易娛樂6月11日報道6月11日幸乒,有八卦媒體曝光曹云金與妻子唐菀現(xiàn)身天津民政局辦理了離婚手續(xù)懦底。對此,網(wǎng)易娛樂向曹云金經(jīng)紀(jì)人求證罕扎,得到了對方獨家回應(yīng):“確實是離婚",
          "id" : 214,
          "title" : "曹云金承認已離婚:和平離婚 有人惡意中傷心思歹毒"
        },
        "sort" : [
          1560244657000
        ]
      }
    ]
  }
}

返回結(jié)果中took表示耗時聚唐,_shards表示分片信息,當(dāng)前index有3個分片腔召,并且3個分片都工作正常杆查,hits表示命中的結(jié)果,total表示命中總數(shù)宴咧,max_score表示最大的分值根灯,hits表示命中的具體document。
查詢分為精確過濾(filter)和全文搜索(query)兩種:精確過濾容易被緩存掺栅,因此它的執(zhí)行速度非忱臃危快。

2.2 Filter

2.2.1 term

term 查找可以精確的找到符合條件的記錄氧卧,其中的FIELD標(biāo)識索引中的字段桃笙,VALUE表示需要查詢的值∩尘基本的查詢語句如下:

{
  "term": {
    "FIELD": {
      "value": "VALUE"
    }
  }
}

比如搏明,查詢source為中新經(jīng)緯的新聞,那么可以這么使用:

GET /news/_search
{
  "query": {"term": {
    "source": {
      "value": "中新經(jīng)緯"
    }
  }}
}

2.2.2 bool

當(dāng)需要多個邏輯組合查詢的時候闪檬,可以使用bool來組各邏輯星著。bool可以包含

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
   }
}

must:搜索的結(jié)果必須匹配,類似SQL的AND
must_not: 搜索的結(jié)果必須不匹配粗悯,類似SQL的NOT
should: 搜索的結(jié)果至少匹配到一個虚循,類似SQL的OR
當(dāng)我們需要查source為中新經(jīng)緯,并且id為4或者75的新聞样傍,可以這樣使用:

GET /news/_search
{
  "query": {
    "bool": {
    "must": [
    {"term": {
      "source": {
        "value": "中新經(jīng)緯"
      }
    }}
  ],
  "should": [
    {"term": {
      "id": {
        "value": "4"
      }
    }},
    {"term": {
      "id": {
        "value": "75"
      }
    }}
  ],
  "minimum_should_match": 1
  }}
}

其中的minimun_should_match用來指定should內(nèi)的條件需要匹配多少個横缔,默認是0,0的情況下should內(nèi)容只參與打分衫哥,不做倒排過濾茎刚。

2.2.3 terms

對于上面查找多個精確值的情況,可以使用terms撤逢,比如查找id是4或者75的文章膛锭,可以這么使用:

GET /news/_search
{
  "query": {"terms": {
    "id": [
      "4",
      "75"
    ]
  }}
}

2.2.4 range

對于需要用到范圍的查詢,可以使用range蚊荣,range和term作用的位置相同初狰,比如查找id從1到10的文章

GET /news/_search
{
  "query": {"range": {
    "id": {
      "gte": 1,
      "lte": 10
    }
  }}
}

其中:

  • gt: > 大于(greater than)
  • lt: < 小于(less than)
  • gte: >= 大于或等于(greater than or equal to)
  • lte: <= 小于或等于(less than or equal to)

2.2.5 exists

es中可以使用exists來查找某個字段存在或者不存在的document,比如查找存在author字段的文檔妇押,也可以在bool內(nèi)配合should和must_not使用跷究,就可以實現(xiàn)不存在或者可能存在的查詢。

GET /news/_search
{
  "query": {
    "exists": {"field": "author"}
  }
}

2.3 Query

和filter的精確匹配不一樣敲霍,query可以進行一些字段的全文搜索和搜索結(jié)果打分俊马,es中只有類型為text的字段才可以被分詞,類型為keyword雖然也是字符串肩杈,但只能作為枚舉柴我,不能被分詞,text的分詞類型可以在創(chuàng)建索引的時候指定扩然。

2.3.1 match

當(dāng)我們想要搜某個字段的時候可以使用match艘儒,比如查找文章中出現(xiàn)體育的新聞,可以這樣查詢

GET /news/_search
{
  "query": {
    "match": {"summary":"體育" }
  }
}

在match中我們還可以指定分詞器,比如指定分詞器為ik_smart對輸入的詞盡量分大顆粒界睁,此時召回的就是含有進口紅酒的document觉增,如果指定分詞器為ik_max_word則分出的詞顆粒會比較小,會召回包含口紅和紅酒的document

{
    "match": {
      "name": {
        "query": "進口紅酒",
        "analyzer": "ik_smart"
      }
    
    }
  }

對于query的文本有可能分出好幾個詞翻斟,這個時候可以用and連接逾礁,表示多個詞都命中才被召回,如果用or連接访惜,則類似should可以控制嘹履,至少命中多少個詞才被召回。比如搜索包含體育新聞內(nèi)容的新聞债热,下面這個查詢只要包含一個體育或者新聞的document都會被召回

GET /news/_search
{
  "query": {
    "match": {
      "summary": {
        "query": "體育新聞",
        "operator": "or",
        "minimum_should_match": 1
      }
    }
  }
}

2.3.2 multi_match

當(dāng)需要搜索多個字段的時候砾嫉,可以使用multi_match進行查詢,比如在title或者summary中搜索含有新聞關(guān)鍵詞的document

GET /news/_search
{
  "query": {
    "multi_match": {
      "query": "新聞",
      "fields": ["title", "summary"]
    }
  }
}

2.4 組合查詢

    有了全文搜索和過濾的這些字段窒篱,配合bool就可以實現(xiàn)復(fù)雜的組合查詢
GET /news/_search
{
  "query": {"bool": {
    "must": [
      {"match": {
        "summary": {
          "boost": 1,
          "query": "長安"
        }
      }
      },
      {
        "term": {
          "source": {
            "value": "中新經(jīng)緯",
            "boost": 2
          }
        }
      }
    ],
    "filter": {"bool": {
      "must":[
        {"term":{
          "id":75
        }}
        ]
    }}
  }}
}

上面請求bool中的must焕刮、must_not、should可以使用term舌剂,range济锄、match。這些默認都是參與打分的霍转,可以通過boost來控制打分的權(quán)重荐绝,如果不想要某些查詢條件參與打分,可以在bool中添加filter避消,這個filter中的查詢字段都不參與打分低滩,而且查詢的內(nèi)容可以被緩存。

3.聚合

聚合的基本格式為:

GET /news/_search
{
  "size": 0,
  "aggs": {
    "NAME": {
      "AGG_TYPE": {}
    }
  }
}

其中NAME表示當(dāng)前聚合的名字岩喷,可以取任意合法的字符串恕沫,AGG_TYPE表示聚合的類型,常見的為分為多值聚合和單值聚合

3.1 一個聚合的例子

GET /news/_search
{
 "size": 0, 
  "aggs": {
    "sum_all": {
      "sum": {
        "field": "replyCount"
      }
    }
  }
}

上面的例子表示查詢當(dāng)前庫里面的replayCount的和纱意,返回結(jié)果:

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 204,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "sum_all" : {
      "value" : 390011.0
    }
  }
}

返回結(jié)果中默認會包含命中的document婶溯,所以需要把size指定為0,結(jié)果中的sum_all為請求中指定的名字偷霉。
Elasticsearch中的聚合類型主要分為Metrics和Bucket

3.2 Metrics

metrics主要是一些單值的返回迄委,像avg、max类少、min叙身、sum、stats等這些計算硫狞。

3.2.1 max

比如計算index里面最多的點贊數(shù)是多少信轿,可以這樣使用晃痴,max、avg财忽、min倘核、sum使用類似

GET /news/_search
{
  "size": 0,
  "aggs": {
    "max_replay": {
      "max": {
        "field": "replyCount"
      }
    }
  }
}

3.2.2 stats

常用的一些統(tǒng)計信息,可以用stats定罢,比如查看某個字段的笤虫,總數(shù)旁瘫,最小值祖凫,最大值,平均值等酬凳,比如查看document中新聞回復(fù)量的基本情況惠况,stats就是統(tǒng)計的綜合使用。比如請求如下:

GET /news/_search
{
 "size": 0, 
  "aggs": {
    "cate": {
      "stats": {
        "field": "replyCount"
      }
    }
  }
}

返回結(jié)果為:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 204,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "cate" : {
      "count" : 202,
      "min" : 0.0,
      "max" : 32534.0,
      "avg" : 1930.7475247524753,
      "sum" : 390011.0
    }
  }
}```

能返回基本的統(tǒng)計信息

3.3 Bucket

桶類似于sql里面的group by宁仔,使用Bucket會對內(nèi)容進行分桶

3.3.1 terms

利用terms分桶之后稠屠,可以查看數(shù)據(jù)的分布,比如可以查看index中一共有多少個source翎苫,每個source有多少文章权埠,size是用來指定返回最多的幾個分類,可以這樣使用:

GET /test_ratings_v1/_search
{
  "size": 0, 
  "aggs": {
    "myterms": {
      "terms": {
        "field": "productId",
        "size": 10
      }
    }
  }
}

表示對productId進行分桶煎谍,返回每個桶的個數(shù)攘蔽。外層的size表示不返回命中的數(shù)據(jù),只返回聚合結(jié)果

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 10002,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "myterms" : {
      "doc_count_error_upper_bound" : 69,
      "sum_other_doc_count" : 5701,
      "buckets" : [
        {
          "key" : 452966,
          "doc_count" : 1168
        },
        {
          "key" : 452734,
          "doc_count" : 608
        },
        {
          "key" : 453353,
          "doc_count" : 592
        },
        {
          "key" : 453231,
          "doc_count" : 522
        },
        {
          "key" : 453275,
          "doc_count" : 387
        },
        {
          "key" : 452639,
          "doc_count" : 273
        },
        {
          "key" : 453104,
          "doc_count" : 236
        },
        {
          "key" : 452679,
          "doc_count" : 180
        },
        {
          "key" : 453152,
          "doc_count" : 169
        },
        {
          "key" : 452640,
          "doc_count" : 165
        }
      ]
    }
  }
}

返回結(jié)果key表示productId呐粘,doc_count表示數(shù)目

3.3.2 range

除了按值進行聚合满俗,還可以按范圍進行聚合,比如作岖,求rating的值3-4和小于3唆垃,大于4的統(tǒng)計,可以這樣寫

{
  "size": 0, 
  "aggs": {
    "myterms": {
      "range": {
        "field": "rating",
        "ranges": [
          {
            "from": 3,
            "to": 4
          },
          {
            "from": 4
          },
          {
            "to":3
          }
        ]
      }
    }
  }
}

得到返回結(jié)果:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 10002,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "myterms" : {
      "buckets" : [
        {
          "key" : "*-3.0",
          "to" : 3.0,
          "doc_count" : 1101
        },
        {
          "key" : "3.0-4.0",
          "from" : 3.0,
          "to" : 4.0,
          "doc_count" : 1464
        },
        {
          "key" : "4.0-*",
          "from" : 4.0,
          "doc_count" : 7436
        }
      ]
    }
  }
}

可以看到小于3的有1101個痘儡,3-4的有1464個辕万,而大于4的有7436個。

3.4 組合聚類

GET /news/_search
{
  "size": 0,
  "aggs": {
    "myterms": {
      "terms": {
        "field": "source",
        "size": 100
      },
      "aggs": {
        "replay": {
          "terms": {
            "field": "replyCount",
            "size": 10
          }
        },
        "avg_price": { 
            "avg": {
                  "field": "voteCount"
               }
            }
      }
    }
  }
}

上面代碼首先對source分桶沉删,在每個souce類型里面在對replayCount進行分桶渐尿,并且計算每個source類里面的voteCount的平均值
由于返回結(jié)果比較大,這里只給出返回的某一個桶結(jié)果:

{
          "key" : "中國新聞網(wǎng)",
          "doc_count" : 16,
          "avg_price" : {
            "value" : 1195.0
          },
          "replay" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 4,
            "buckets" : [
              {
                "key" : 0,
                "doc_count" : 3
              },
              {
                "key" : 1,
                "doc_count" : 1
              },
              {
                "key" : 5,
                "doc_count" : 1
              },
              {
                "key" : 32,
                "doc_count" : 1
              },
              {
                "key" : 97,
                "doc_count" : 1
              },
              {
                "key" : 106,
                "doc_count" : 1
              },
              {
                "key" : 133,
                "doc_count" : 1
              },
              {
                "key" : 155,
                "doc_count" : 1
              },
              {
                "key" : 156,
                "doc_count" : 1
              },
              {
                "key" : 248,
                "doc_count" : 1
              }
            ]
          }
        }

4.查詢和聚合的組合使用

有了查詢和聚合丑念,我們就可以對查詢的結(jié)果做聚合涡戳,比如我想查看summary中包含體育的新聞都是那些來源網(wǎng)站,就可以像下面這樣查詢:

GET /news/_search
{
 "size": 0, 
 "query": {"bool": {"must": [
   {"match": {
     "summary": "體育"
   }}
 ]}}, 
  "aggs": {
    "cate": {
      "terms": {
        "field": "source"
      }
    }
  }
}

5.總結(jié)

Elasticsearch的查詢語法比較復(fù)雜和多樣脯倚,這里只例舉了常見的一些查詢和聚合渔彰,詳細可以參考官方文檔和權(quán)威指南嵌屎,權(quán)威指南由于是中文,閱讀比較方便恍涂,但是是2.x的內(nèi)容宝惰,官方文檔有對應(yīng)版本的內(nèi)容,內(nèi)容比較新再沧,建議閱讀官方文檔尼夺。
Elasticsearch權(quán)威指南(中文)
Elasticsearch6.5 官方文檔(英文)
更多精彩內(nèi)容,請關(guān)注公眾號

公眾號二維碼.jpg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炒瘸,一起剝皮案震驚了整個濱河市淤堵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌顷扩,老刑警劉巖拐邪,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜒谤,死亡現(xiàn)場離奇詭異颖御,居然都是意外死亡,警方通過查閱死者的電腦和手機上沐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門婶芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來东臀,“玉大人,你說我怎么就攤上這事犀农《韪常” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵井赌,是天一觀的道長谤逼。 經(jīng)常有香客問我,道長仇穗,這世上最難降的妖魔是什么流部? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮纹坐,結(jié)果婚禮上枝冀,老公的妹妹穿的比我還像新娘。我一直安慰自己耘子,他們只是感情好果漾,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谷誓,像睡著了一般绒障。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捍歪,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天户辱,我揣著相機與錄音鸵钝,去河邊找鬼。 笑死庐镐,一個胖子當(dāng)著我的面吹牛恩商,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播必逆,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼怠堪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了名眉?” 一聲冷哼從身側(cè)響起粟矿,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎璧针,沒想到半個月后嚷炉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡探橱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绘证。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隧膏。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嚷那,靈堂內(nèi)的尸體忽然破棺而出胞枕,到底是詐尸還是另有隱情,我是刑警寧澤魏宽,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布腐泻,位于F島的核電站,受9級特大地震影響队询,放射性物質(zhì)發(fā)生泄漏派桩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一蚌斩、第九天 我趴在偏房一處隱蔽的房頂上張望铆惑。 院中可真熱鬧,春花似錦送膳、人聲如沸员魏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撕阎。三九已至,卻和暖如春碌补,著一層夾襖步出監(jiān)牢的瞬間虏束,已是汗流浹背名斟。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留魄眉,地道東北人砰盐。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像坑律,于是被迫代替她去往敵國和親岩梳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容