1. 程式人生 > >Elasticsearch搜尋詳解(二):請求體搜尋

Elasticsearch搜尋詳解(二):請求體搜尋

上一篇文章介紹了基於 url 的搜尋,這次要講一種更高階的搜尋方法——請求體搜尋(Request Body Search),搜尋引數不是寫在 url 上,而是作為請求的資料傳送。利用 Query DSL 的語法可以組合出更加靈活的搜尋。

簡單的例子

GET /customer/_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

對應的curl 格式是:

curl -X GET "localhost:9200/customer/_search" -H 'Content-Type: application/json' -d'
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
'

查詢返回的結果

{
    "took": 1,
    "timed_out": false,
    "_shards":{
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits":{
        "total" : 1,
        "max_score": 1.3862944,
        "hits" : [
            {
                "_index" : "twitter",
                "_type" : "_doc",
                "_id" : "0",
                "_score": 1.3862944,
                "_source" : {
                    "user" : "kimchy",
                    "message": "trying out Elasticsearch",
                    "date" : "2009-11-15T14:12:12",
                    "likes" : 0
                }
            }
        ]
    }
}

當過本次查詢的統計,和查詢到的文件。

from 和 size

與關係資料庫類似,ES也可以指定from 和 size,舉上面的例子

GET /customer/_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    },
    from: 0,
    size: 20
}

from 從0開始,size 最大不能大於 index.max_result_window 的配置,預設是10000。

排序 sort

可以指定某個或者多個欄位作為排序欄位。有兩個特殊的排序欄位,_score 和 _doc,_score 是文件匹配的 score,_doc 是文件索引時候的順序。

在能夠使用sort之前,必須為排序的欄位指定型別(須在建立索引之前完成),例如

PUT /my_index
{
    "mappings": {
        "_doc": {
            "properties": {
                "post_date": { "type": "date" },
                "user": {
                    "type": "keyword"
                },
                "name": {
                    "type": "keyword"
                },
                "age": { "type": "integer" }
            }
        }
    }
}

然後就可以指定欄位排序了,兩種順序 asc 和 desc

GET /my_index/_search
{
    "sort" : [
        { "post_date" : {"order" : "asc"}},
        "user",
        { "name" : "desc" },
        { "age" : "desc" },
        "_score"
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

sort mode

當排序的欄位是陣列的時候,該如何告訴 ES 排序呢?sort 還可以指定 mode 屬性,min,max,sum,avg,或者 median,含義如字面理解的一樣。

舉例

PUT /my_index/_doc/1?refresh
{
   "product": "chocolate",
   "price": [20, 4]
}

GET /my_index/_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
      {"price" : {"order" : "asc", "mode" : "avg"}}
   ]
}

sort nexted

當排序的欄位是個物件裡的屬性該怎麼辦?例如 offer.price,

POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
       {
          "offer.price" : {
             "mode" :  "avg",
             "order" : "asc",
             "nested": {
                "path": "offer",
                "filter": {
                   "term" : { "offer.color" : "blue" }
                }
             }
          }
       }
    ]
}

offer.price 是自定義的排序名稱,必要的關鍵字時 nested 和 path,path 表示排序的屬性是哪個物件的屬性;filter 可選,一幫跟 query 的查詢條件一樣。