1. 程式人生 > >Es學習第六課, ES基本搜尋_search

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

多索引和多類別

你注意到空搜尋的結果中不同型別的文件——usertweet——來自於不同的索引——usgb

通過限制搜尋的不同索引或型別,我們可以在叢集中跨所有文件搜尋。Elasticsearch轉發搜尋請求到叢集中平行的主分片或每個分片的複製分片上,收集結果後選擇頂部十個返回給我們。

通常,當然,你可能想搜尋一個或幾個自定的索引或型別,我們能通過定義URL中的索引或型別達到這個目的,像這樣:

在所有索引的所有型別中搜索

/gb/_search

在索引gb的所有型別中搜索

/gb,us/_search

在索引gbus的所有型別中搜索

/g*,u*/_search

在以gu開頭的索引的所有型別中搜索

/gb/user/_search

在索引gb的型別user中搜索

/gb,us/user,tweet/_search

在索引gbus的型別為usertweet中搜索

/_all/user,tweet/_search

在所有索引的usertweet中搜索 search types user and tweet in all indices

當你搜索包含單一索引時,Elasticsearch轉發搜尋請求到這個索引的主分片或每個分片的複製分片上,然後聚集每個分片的結果。搜尋包含多個索引也是同樣的方式——只不過或有更多的分片被關聯。

分頁

和SQL使用LIMIT關鍵字返回只有一頁的結果一樣,Elasticsearch接受fromsize引數:

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欄位搜尋。