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處理