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
字段搜索。
Es學習第六課, ES基本搜索_search