Es學習第六課, ES基本搜尋_search
前面幾課ES的基本概念、安裝和分詞都講過了,下面我們就來實戰一下ES的核心功能-搜尋,這節課我們主要講的是基本搜尋 _search(注意:ES的關鍵字都要加字首_,所以我們在定義索引、型別名稱時不要帶_)。
我們先通過kibana插入幾條三個文件
PUT /customer/doc/1?pretty
{
"name": "John Doe"
}
POST /customer/doc/
{
"title": "My second blog entry",
"text": "Still trying this out...",
"date": "2014/01/01 "
}
POST /website/blog/1/_update
{
"doc" : {
"tags" : [ "testing" ],
"views": 0
}
}
_search
最基本的搜尋API表單是空搜尋(empty search),它沒有指定任何的查詢條件,只返回叢集索引中的所有文件:
GET /_search
執行上面命令後會有下面返回結果:
{ "took": 4, "timed_out": false, "_shards": { "total": 10, "successful": 10, "skipped": 0, "failed": 0 }, "hits": { "total": 3, "max_score": 1, "hits": [ { "_index": "customer", "_type": "doc", "_id": "gMHxC2cBvsiyaz9P4LEH", "_score": 1, "_source": { "title": "My second blog entry", "text": "Still trying this out...", "date": "2014/01/01" } }, { "_index": "customer", "_type": "doc", "_id": "1", "_score": 1, "_source": { "name": "John Doe" } }, { "_index": "website", "_type": "blog", "_id": "1", "_score": 1, "_source": { "title": "My first blog entry", "text": "Starting to get the this...", "views": 1, "tags": [ "testing" ] } } ] } }
針對上面返回結果,一些關鍵field的解釋如下:
hits
響應中最重要的部分是hits
,它包含了total
欄位來表示匹配到的文件總數,hits
陣列還包含了匹配到的前10條資料。
hits
陣列中的每個結果都包含_index
、_type
和文件的_id
欄位,被加入到_source
欄位中這意味著在搜尋結果中我們將可以直接使用全部文件。這不像其他搜尋引擎只返回文件ID,需要你單獨去獲取文件。
每個節點都有一個_score
欄位,這是相關性得分(relevance score),它衡量了文件與查詢的匹配程度。預設的,返回的結果中關聯性最大的文件排在首位;這意味著,它是按照_score
_score
都是取得一箇中間值1
max_score
指的是所有文件匹配查詢中_score
的最大值。
took
took
告訴我們整個搜尋請求花費的毫秒數。
shards
_shards
節點告訴我們參與查詢的分片數(total
欄位),有多少是成功的(successful
欄位),有多少的是失敗的(failed
欄位)。通常我們不希望分片失敗,不過這個有可能發生。如果我們遭受一些重大的故障導致主分片和複製分片都故障,那這個分片的資料將無法響應給搜尋請求。這種情況下,Elasticsearch將報告分片failed
,但仍將繼續返回剩餘分片上的結果。
timeout
time_out
值告訴我們查詢超時與否。一般的,搜尋請求不會超時。如果響應速度比完整的結果更重要,你可以定義timeout
引數為10
或者10ms
(10毫秒),或者1s
(1秒)
GET /_search?timeout=10ms
多索引和多類別
你注意到空搜尋的結果中不同型別的文件——user
和tweet
——來自於不同的索引——us
和gb
。
通過限制搜尋的不同索引或型別,我們可以在叢集中跨所有文件搜尋。Elasticsearch轉發搜尋請求到叢集中平行的主分片或每個分片的複製分片上,收集結果後選擇頂部十個返回給我們。
通常,當然,你可能想搜尋一個或幾個自定的索引或型別,我們能通過定義URL中的索引或型別達到這個目的,像這樣:
/_search
在所有索引的所有型別中搜索
/gb/_search
在索引gb
的所有型別中搜索
/gb,us/_search
在索引gb
和us
的所有型別中搜索
/g*,u*/_search
在以g
或u
開頭的索引的所有型別中搜索
/gb/user/_search
在索引gb
的型別user
中搜索
/gb,us/user,tweet/_search
在索引gb
和us
的型別為user
和tweet
中搜索
/_all/user,tweet/_search
在所有索引的user
和tweet
中搜索 search types user
and tweet
in all indices
當你搜索包含單一索引時,Elasticsearch轉發搜尋請求到這個索引的主分片或每個分片的複製分片上,然後聚集每個分片的結果。搜尋包含多個索引也是同樣的方式——只不過或有更多的分片被關聯。
分頁
和SQL使用LIMIT
關鍵字返回只有一頁的結果一樣,Elasticsearch接受from
和size
引數:
size
: 結果數,預設10
from
: 跳過開始的結果數,預設0
如果你想每頁顯示5個結果,頁碼從1到3,那請求如下:
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
簡易搜尋
search
API有兩種表單:一種是“簡易版”的查詢字串(query string)將所有引數通過查詢字串定義,另一種版本使用JSON完整的表示請求體(request body),這種富搜尋語言叫做結構化查詢語句(DSL)
查詢字串搜尋對於在命令列下執行點對點(ad hoc)查詢特別有用。例如這個語句查詢所有文件中並在name欄位中包含john
字元的文件:
GET /_all/_search?q=name:john
_all
欄位
返回包含"mary"
字元的所有文件的簡單搜尋:
GET /_search?q=mary
當你索引一個文件,Elasticsearch把所有字串欄位值連線起來放在一個大字串中,它被索引為一個特殊的欄位_all
。例如,當索引這個文件:
{
"tweet": "However did I manage before Elasticsearch?",
"date": "2014-09-14", "name": "Mary Jones", "user_id": 1 }
這好比我們增加了一個叫做_all
的額外欄位值:
"However did I manage before Elasticsearch? 2014-09-14 Mary Jones 1"
若沒有指定欄位,查詢字串搜尋(即q=xxx)使用_all
欄位搜尋。