1. 程式人生 > >ElasticSearch學習筆記之十八 排序Sort

ElasticSearch學習筆記之十八 排序Sort

Sort

Elasticsearch 允許你在特性的欄位上進行一次或者多次排序,每次排序都是可以顛倒的,_score欄位用來按照相關性得分排序, _doc 按照順序來排序。

新建索引如下:

PUT /my_index
{
    "mappings": {
        "_doc": {
            "properties": {
                "post_date": { "type": "date" },
                "user": {
                    "type": "keyword"
                }
, "name": { "type": "keyword" }, "age": { "type": "integer" } } } } }
GET /my_index/_search
{
    "sort" : [
        { "post_date" : {"order" : "asc"}},
        "user",
        { "name" : "desc" },
        { "age"
: "desc" }, "_score" ], "query" : { "term" : { "user" : "kimchy" } } }

_doc 是最高效的排序以外,基本很少使用。因此,如果您不關心文件返回的順序,那麼您應該根據_doc進行排序。這在滾動時特別有用。

Sort Values

sort values將作為文件返回的一部分一起返回。

Sort Order

order 有以下取值:

取值 說明
asc 遞增
desc 遞減

當是_score排序時預設按照desc, 其他預設使用 asc

Sort mode option

Elasticsearch 排序支援多指或者陣列,mode option用來挑選陣列的值來對文件排序, mode option 有以下取值:

取值 說明
min 最小值
max 最大值
sum 所有值的和 (只適用陣列)
avg 平均值 (只使用陣列)
median 中值 (只使用陣列)

Sort mode 舉例:
下面文件中的價格有多個取值。我們希望按照檔案平均價格遞增排序

PUT /my_index/_doc/1?refresh
{
   "product": "chocolate",
   "price": [20, 4]
}
POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
      {"price" : {"order" : "asc", "mode" : "avg"}}
   ]
}

Sorting within nested objects

Elasticsearch 也支援巢狀物件的排序,巢狀物件的排序的 nested sort option有以下取值:

取值 說明
path 定義要排序的巢狀物件。實際排序欄位必須是巢狀物件內的欄位。當由巢狀欄位排序時,此欄位是強制的。
filter nested path 內部的巢狀物件的過濾器, 以便通過利用其欄位值來排序,通常情況下是在巢狀物件內部的重複query / filter。預設情況下沒有nested_filter 是啟用的
nested 與頂級巢狀物件相同,但適用於當前巢狀物件中的另一個巢狀路徑。

注意:
nested_path 和nested_filter 在Elasticseach 6.1之後棄用。

Nested sorting 舉例
nested path 需要被明確指明,否則 Elasticsearch 不知道巢狀物件級的排序

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

下面的案例中parent和 child 都是巢狀型別的欄位。 nested_path 需要在每一個巢狀層級指明; 否則, Elasticsearch 不知道對應層級的排序

POST /_search
{
   "query": {
      "nested": {
         "path": "parent",
         "query": {
            "bool": {
                "must": {"range": {"parent.age": {"gte": 21}}},
                "filter": {
                    "nested": {
                        "path": "parent.child",
                        "query": {"match": {"parent.child.name": "matt"}}
                    }
                }
            }
         }
      }
   },
   "sort" : [
      {
         "parent.child.age" : {
            "mode" :  "min",
            "order" : "asc",
            "nested": {
               "path": "parent",
               "filter": {
                  "range": {"parent.age": {"gte": 21}}
               },
               "nested": {
                  "path": "parent.child",
                  "filter": {
                     "match": {"parent.child.name": "matt"}
                  }
               }
            }
         }
      }
   ]
}

巢狀物件的排序也支援 scripts 指令碼 和 geo distance.

Missing Values

missing 用於對欄位沒有取值的文件的排序,missing 可以取值為_last, _first, 或者自定義值 (自定義會用於缺值文件的排序).預設是 _last.

例如:

GET /_search
{
    "sort" : [
        { "price" : {"missing" : "_last"} }
    ],
    "query" : {
        "term" : { "product" : "chocolate" }
    }
}

注意
巢狀物件的內部物件不匹配nested_filter 那麼就會使用missing.

Ignoring Unmapped Fields

預設情況下,如果對沒有mapping的欄位查詢會失敗. unmapped_type允許你無視沒有mapping的欄位並且不用它們排序 。unmapped_type的取值決定使用什麼排序mapping。
例如:

GET /_search
{
    "sort" : [
        { "price" : {"unmapped_type" : "long"} }
    ],
    "query" : {
        "term" : { "product" : "chocolate" }
    }
}

如果查詢的任一文件price沒有 mapping沒有值,Elasticsearch 將會把它的mapping 當成long處理