觸類旁通Elasticsearch之吊打同行系列:搜索篇
點擊上方藍色字體,選擇“設(shè)為星標”

ES的搜索請求執(zhí)行流程如圖1所示。圖中索引包含兩個分片,每個分片有一個副本分片。在給文檔定位和評分后,缺省只會獲取排名前10的文檔。REST API搜索請求被發(fā)送到所連接的節(jié)點,該節(jié)點根據(jù)要查詢的索引,將這個請求依次發(fā)送到所有的相關(guān)分片(主分片或者副本分片)。從所有分片收集到足夠的排序和排名信息后,只有包含所需文檔的分片被要求返回相關(guān)內(nèi)容。這種搜索路由的行為是可配置的,圖1展示的默認行為,稱為查詢后獲取(query_then_fetch)。

圖1 搜索請求是如何路由的
一、搜索請求的結(jié)構(gòu)
1. 確定搜索范圍
# 無條件搜索整個集群curl '172.16.1.127:9200/_search?pretty'curl '172.16.1.127:9200/_all/_search?pretty'curl '172.16.1.127:9200/*/_search?pretty'# 無條件搜索get-together索引,類似于SQL中的select * from get-together;curl '172.16.1.127:9200/get-together/_search?pretty'# 在ES6中已經(jīng)廢棄了type的概念,所以功能同上curl '172.16.1.127:9200/get-together/_doc/_search?pretty'# 無條件搜索get-together、dbinfo兩個索引curl '172.16.1.127:9200/get-together,dbinfo/_doc/_search?pretty'# 模糊匹配索引名稱,包含get-toge開頭的索引,但不包括get-togethercurl '172.16.1.127:9200/+get-toge*,-get-together/_search?pretty'
2. 搜索請求的基本模塊
select ...? from ...?where ...?order by ...?limit ...? ? ? ? where <-> query? ?select ... <-> _source?? size + from <-> limit? ? ?order by <-> sort
query:配置查詢和過濾器DSL,限制搜索的條件,類似于SQL查詢中的where子句。
size:返回文檔的數(shù)量,類似于SQL查詢中的limit子句中的數(shù)量。
from:和size一起使用,from用于分頁操作,類似于SQL查詢中的limit子句中的偏移量。如果結(jié)果集合不斷增加,獲取某些靠后的翻頁將會成為代價高昂的操作。(SQL中延遲關(guān)聯(lián)的思想應(yīng)該也可用于ES,先搜索出某一頁的ID,再通過ID查詢字段。)
_source:指定_source字段如何返回,默認返回完整的_source字段,類似于SQL中的select *。通過配置_source,將過濾返回的字段。
sort:類似于SQL中的order by子句,用于排序,默認的排序是基于文檔的得分。
# ES的from從0開始curl '172.16.1.127:9200/get-together/_search?from=10&size=10&pretty'
curl '172.16.1.127:9200/get-together/_search?sort=date:asc&pretty'curl '172.16.1.127:9200/get-together/_search?sort=date:asc&_source=title,date&pretty'curl '172.16.1.127:9200/get-together/_search?sort=date:asc&q=title:elasticsearch&pretty'3. 基于請求主體的搜索請求
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_all": {}? },? "from": 10,? "size": 10}'
# 只返回name和date字段curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_all": {}? },? "_source": [? ? "name",? ? "date"? ]}'
# 返回location開頭的字段和日期字段,但不返回location.geolocation字段curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_all": {}? },? "_source": {? ? "include": [? ? ? "location.*",? ? ? "date"? ? ],? ? "exclude": [? ? ? "location.geolocation"? ? ]? }}'
# 類似于SQL中的order by created_on asc, name desc, _scorecurl -XPOST "172.16.1.127:9200/get-together/_mapping/_doc?pretty" -H 'Content-Type: application/json' -d'{? "properties": {? ? "name": {? ? ? "type": "text",? ? ? "fielddata": "true"? ? }? }}'curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_all": {}? },? "sort": [? ? {? ? ? "created_on": "asc"? ? },? ? {? ? ? "name": "desc"? ? },? ? "_score"? ]}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_all": {}? },? "from": 0,? "size": 10,? "_source": [? ? "name",? ? "organizer",? ? "description"? ],? "sort": [? ? {? ? ? "created_on": "desc"? ? }? ]}'
select name, organizer, description? from get-together?order by created_on desc?limit 0, 10;
4. 回復(fù)的結(jié)構(gòu)
curl '172.16.1.127:9200/_search?q=title:elasticsearch&_source=title,date&pretty'{? "took" : 13, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 查詢執(zhí)行所用的毫秒數(shù)? "timed_out" : false, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 是否超時? "_shards" : {? ? "total" : 28, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 搜索的分片數(shù)? ? "successful" : 28, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 成功的分片數(shù)? ? "skipped" : 0, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 跳過的分片數(shù)? ? "failed" : 0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 失敗的分片數(shù)? },? "hits" : {? ? "total" : 7, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 匹配的文檔數(shù)? ? "max_score" : 1.0128567, ? ? ? ? ? ? ? ? ? ? ? ? # 最高文檔得分? ? "hits" : [ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 命中文檔的數(shù)組? ? ? {? ? ? ? "_index" : "get-together", ? ? ? ? ? ? ? ? ? # 文檔所屬索引? ? ? ? "_type" : "_doc", ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 文檔所屬類型? ? ? ? "_id" : "103", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 文檔ID? ? ? ? "_score" : 1.0128567, ? ? ? ? ? ? ? ? ? ? ? ?# 相關(guān)性得分? ? ? ? "_routing" : "2", ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 文檔所屬的分片號? ? ? ? "_source" : { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 請求的_source字段? ? ? ? ? "date" : "2013-04-17T19:00",? ? ? ? ? "title" : "Introduction to Elasticsearch"? ? ? ? }? ? ? },? ? ? {? ? ? ? "_index" : "get-together",? ? ? ? "_type" : "_doc",? ? ? ? "_id" : "105",? ? ? ? "_score" : 1.0128567,? ? ? ? "_routing" : "2",? ? ? ? "_source" : {? ? ? ? ? "date" : "2013-07-17T18:30",? ? ? ? ? "title" : "Elasticsearch and Logstash"? ? ? ? }? ? ? },? ? ? ...? ? ]? }}
二、查詢和過濾器

1. match
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_all": {}? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match": {? ? ? "title": "hadoop"? ? }? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match": {? ? ? "name": {? ? ? ? "query": "Elasticsearch Denver",? ? ? ? "operator": "and"? ? ? }? ? }? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_phrase": {? ? ? "name": {? ? ? ? "query": "enterprise london",? ? ? ? "slop": 1? ? ? }? ? }? },? "_source": [? ? "name",? ? "description"? ]}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "match_phrase_prefix": {? ? ? "name": {? ? ? ? "query": "Elasticsearch den",? ? ? ? "max_expansions": 1? ? ? }? ? }? },? "_source": [? ? "name"? ]}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "multi_match": {? ? ? "query": "elasticsearch hadoop",? ? ? "fields": [? ? ? ? "name",? ? ? ? "description"? ? ? ]? ? }? }}'
2. term
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "term": {? ? ? "tags": "elasticsearch"? ? }? },? "_source": [? ? "name",? ? "tags"? ]}'
和term查詢相似,可以使用term過濾器來限制結(jié)果文檔,使其包含特定的詞條,不過無須計算得分。
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "bool": {? ? ? "filter": {? ? ? ? "term": {? ? ? ? ? "tags": "elasticsearch"? ? ? ? }? ? ? }? ? }? }}'
和term查詢類似,terms查詢可以搜索某個文檔字段中的多個詞條。例如下面的查詢搜索標簽含有“jvm”或“hadoop”的文檔。
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "terms": {? ? ? "tags": [? ? ? ? "jvm",? ? ? ? "hadoop"? ? ? ]? ? }? },? "_source": [? ? "name",? ? "tags"? ]}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "bool": {? ? ? "minimum_should_match": 2,? ? ? "must": {? ? ? ? "terms": {? ? ? ? ? "tags": [? ? ? ? ? ? "jvm",? ? ? ? ? ? "hadoop",? ? ? ? ? ? "lucene"? ? ? ? ? ]? ? ? ? }? ? ? }? ? }? }}'
3. query_string
curl -XGET '172.16.1.127:9200/get-together/_search?q=nosql&pretty'curl -XPOST '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "query_string": {? ? ? "query": "nosql"? ? }? }}'
curl -XPOST '172.16.1.127:9200/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "query_string": {? ? ? "default_field": "description",? ? ? "query": "nosql"? ? }? }}'
curl -XPOST '172.16.1.127:9200/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "query_string": {? ? ? "fields": ["description", "tags"],? ? ? "query": "nosql"? ? }? }}'
curl -XPOST '172.16.1.127:9200/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "query_string": {? ? ? "query": "name:nosql AND -description:mongodb"? ? }? }}'
curl -XPOST '172.16.1.127:9200/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "query_string": {? ? ? "query": "(tags:search OR tags:lucene) AND (created_on:[1999-01-01 TO 2001-01-01])"? ? }? }}'
三、復(fù)合查詢
1. bool查詢
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "bool": {? ? ? "must": [? ? ? ? {? ? ? ? ? "term": {? ? ? ? ? ? "attendees": "david"? ? ? ? ? }? ? ? ? }? ? ? ],? ? ? "should": [? ? ? ? {? ? ? ? ? "term": {? ? ? ? ? ? "attendees": "clint"? ? ? ? ? }? ? ? ? },? ? ? ? {? ? ? ? ? "term": {? ? ? ? ? ? "attendees": "andy"? ? ? ? ? }? ? ? ? }? ? ? ],? ? ? "must_not": [? ? ? ? {? ? ? ? ? "range": {? ? ? ? ? ? "date": {? ? ? ? ? ? ? "lt": "2013-06-30T00:00"? ? ? ? ? ? }? ? ? ? ? }? ? ? ? }? ? ? ],? ? ? "minimum_should_match": 1? ? }? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{"query": {"bool": {"must": [{"term": {"attendees": "david"}},{"range": {"date": {"gte": "2013-06-30T00:00"}}},{"terms": {"attendees": ["clint","andy"]}}]}}}'
2. bool過濾器
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "bool": {? ? ? "filter": {? ? ? ? "bool": {? ? ? ? ? "must": [? ? ? ? ? ? {? ? ? ? ? ? ? "term": {? ? ? ? ? ? ? ? "attendees": "david"? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ],? ? ? ? ? "should": [? ? ? ? ? ? {? ? ? ? ? ? ? "term": {? ? ? ? ? ? ? ? "attendees": "clint"? ? ? ? ? ? ? }? ? ? ? ? ? },? ? ? ? ? ? {? ? ? ? ? ? ? "term": {? ? ? ? ? ? ? ? "attendees": "andy"? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ],? ? ? ? ? "must_not": [? ? ? ? ? ? {? ? ? ? ? ? ? "range": {? ? ? ? ? ? ? ? "date": {? ? ? ? ? ? ? ? ? "lt": "2013-06-30T00:00"? ? ? ? ? ? ? ? }? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ]? ? ? ? }? ? ? }? ? }? }}'
四、其它查詢和過濾器
1. range查詢和過濾器
# where created_on > 2012-06-01 and created_on < 2012-09-01curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "range": {? ? ? "created_on": {? ? ? ? "gt": "2012-06-01",? ? ? ? "lt": "2012-09-01"? ? ? }? ? }? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "bool": {? ? ? "filter": {? ? ? ? "range": {? ? ? ? ? "created_on": {? ? ? ? ? ? "gt": "2012-06-01",? ? ? ? ? ? "lt": "2012-09-01"? ? ? ? ? }? ? ? ? }? ? ? }? ? }? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "range": {? ? ? "name": {? ? ? ? "gt": "c",? ? ? ? "lt": "e"? ? ? }? ? }? }}'
2. prefix查詢和過濾器
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "prefix": {? ? ? "title": "liber"? ? }? }}'
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d '{? "query": {? ? "bool": {? ? ? "filter": {? ? ? ? "prefix": {? ? ? ? ? "title": "liber"? ? ? ? }? ? ? }? ? }? }}'
3. wildcard查詢
# 創(chuàng)建索引,添加兩個文檔curl -XPOST '172.16.1.127:9200/wildcard-test/_doc/1?pretty' -H 'Content-Type: application/json' -d '{? "title":"The Best Bacon Ever"}'curl -XPOST '172.16.1.127:9200/wildcard-test/_doc/2?pretty' -H 'Content-Type: application/json' -d '{? "title":"How to raise a barn"}'# “ba*n”會匹配bacon和barncurl '172.16.1.127:9200/wildcard-test/_search?pretty' -H 'Content-Type: application/json' -d'{? "query": {? ? "wildcard": {? ? ? "title": {? ? ? ? "wildcard": "ba*n"? ? ? }? ? }? }}'# “ba?n”只會匹配barn,不會匹配baconcurl '172.16.1.127:9200/wildcard-test/_search?pretty' -H 'Content-Type: application/json' -d'{? "query": {? ? "wildcard": {? ? ? "title": {? ? ? ? "wildcard": "ba?n"? ? ? }? ? }? }}'
4. exists過濾器
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d'{? "query": {? ? "bool": {? ? ? "filter": {? ? ? ? "exists": {? ? ? ? ? "field": "location_event.geolocation"? ? ? ? }? ? ? }? ? }? }}'
5. missing過濾器
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d'{? "query": {? ? "bool": {? ? ? "must_not": {? ? ? ? "exists": {? ? ? ? ? "field": "reviews"? ? ? ? }? ? ? }? ? }? }}'
6. 將任何查詢轉(zhuǎn)變?yōu)檫^濾器
curl '172.16.1.127:9200/get-together/_search?pretty' -H 'Content-Type: application/json' -d'{? "query": {? ? "bool": {? ? ? "filter": {? ? ? ? "query_string": {? ? ? ? ? "query": "name:\"Elasticsearch\""? ? ? ? }? ? ? }? ? }? }}'
五、為任務(wù)選擇最好的查詢

版權(quán)聲明:
文章不錯?點個【在看】吧!??
評論
圖片
表情




