排序(排序)
Sort
允许在特定字段上添加一个或多个排序。每种排序也可以颠倒。排序在每个字段级别定义,_score的特殊字段名称按照评分排序,_doc按索引顺序排序。
假设以下索引映射:
PUT /my_index { "mappings": { "my_type": { "properties": { "post_date": { "type": "date" }, "user": { "type": "keyword" }, "name": { "type": "keyword" }, "age": { "type": "integer" } } } } }
GET /my_index/my_type/_search { "sort" : [ { "post_date" : {"order" : "asc"}}, "user", { "name" : "desc" }, { "age" : "desc" }, "_score" ], "query" : { "term" : { "user" : "kimchy" } } }
注意:除了最有效的排序顺序之外,_doc还没有真正的用例。所以如果你不关心文档的返回顺序,那么你应该按_doc排序。这在滚动时尤其有帮助。
Sort Values
返回的每个文档的排序值也作为响应的一部分返回。
Sort Order
order选项可以具有以下值:
|
按升序排列 |
|
按降序排列 |
在_score排序时,订单默认为desc,并且在其他任何内容排序时默认为asc。
Sort mode option(排序模式选项)
Elasticsearch支持通过数组或多值字段进行排序。mode选项控制选择哪个数组值来排序它所属的文档。mode选项可以具有以下值:
|
选择最低值。 |
|
选择最高值。 |
|
使用所有值的和作为排序值。仅适用于基于数字的数组字段。 |
|
使用所有值的平均值作为排序值。仅适用于基于数字的数组字段。 |
|
使用所有值的中位数作为排序值。仅适用于基于数字的数组字段。 |
Sort mode example usage(排序模式示例用法)
在下面的示例中,每个文档价格字段有多个价格。在这种情况下,结果匹配将根据每个文档的平均价格按升序排序。
PUT /my_index/my_type/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_path
定义要排序的嵌套对象。实际排序字段必须是此嵌套对象内的直接字段。当通过嵌套字段排序时,此字段是必需的。
nested_filter
嵌套路径中的内部对象应该匹配的过滤器,以便通过排序来考虑其字段值。常见的情况是重复嵌套过滤器或查询中的query/filter。默认情况下没有nested_filter是活动的。
Nested sorting example
在下面的示例中,offer是一个nested类型的字段。需要指定nested_path;否则,elasticsearch 不知道需要捕获什么嵌套级排序值。
POST /_search { "query" : { "term" : { "product" : "chocolate" } }, "sort" : [ { "offer.price" : { "mode" : "avg", "order" : "asc", "nested_path" : "offer", "nested_filter" : { "term" : { "offer.color" : "blue" } } } } ] }
通过脚本排序和按距离排序也支持嵌套排序。
Missing Values
missing参数指定如何处理缺少该字段的文档:missing值可以设置为_last,_first或自定义值(将用于缺少文档作为排序值)。例如:
GET /_search { "sort" : [ { "price" : {"missing" : "_last"} } ], "query" : { "term" : { "product" : "chocolate" } } }
注意:如果嵌套的内部对象与nested_filter不匹配,则使用缺少的值。
Ignoring Unmapped Fields(忽略未映射的字段)
默认情况下,如果没有与字段关联的映射,则搜索请求将失败。unmapped_type选项允许忽略没有映射的字段,而不对它们进行排序。此参数的值用于确定要排放的排序值。这是一个如何使用它的例子:
GET /_search { "sort" : [ { "price" : {"unmapped_type" : "long"} } ], "query" : { "term" : { "product" : "chocolate" } } }
如果查询中的任何一个索引都没有price映射,那么Elasticsearch将处理它,就好像有一个类型为long的映射,该索引中的所有文档都没有该字段的值。
Geo Distance Sorting(地理距离排序)
允许通过_geo_distance进行排序。这里是一个例子,假设pin.location是一个类型为geo_point的字段:
GET /_search { "sort" : [ { "_geo_distance" : { "pin.location" : [-70, 40], "order" : "asc", "unit" : "km", "mode" : "min", "distance_type" : "sloppy_arc" } } ], "query" : { "term" : { "user" : "kimchy" } } }
distance_type
如何计算距离。可以是sloppy_arc(默认),arc
(稍微更精确但明显更慢)或plane(更快,但长距离不准确,靠近极点)。
mode
如果一个字段有几个地理位置,该怎么办。默认情况下,按照升序排列时,要考虑最短距离并且按照降序排序时考虑最长距离。支持值的min,max,median和avg。
unit
计算排序值时使用的单位。默认值为m(米)。
注意:地理距离排序不支持可配置的缺失值:当文档没有用于距离计算的字段的值时,距离将始终被视为等于无穷大。
以下格式支持在坐标中提供:
Lat Lon as Properties
GET /_search { "sort" : [ { "_geo_distance" : { "pin.location" : { "lat" : 40, "lon" : -70 }, "order" : "asc", "unit" : "km" } } ], "query" : { "term" : { "user" : "kimchy" } } }
Lat Lon as String
格式化在lat,lon。
GET /_search { "sort" : [ { "_geo_distance" : { "pin.location" : "40,-70", "order" : "asc", "unit" : "km" } } ], "query" : { "term" : { "user" : "kimchy" } } }
Geohash
GET /_search { "sort" : [ { "_geo_distance" : { "pin.location" : "drm3btev3e86", "order" : "asc", "unit" : "km" } } ], "query" : { "term" : { "user" : "kimchy" } } }
Lat Lon as Array
格式在[lon,lat]中,注意,这里的lon / lat的顺序是为了符合GeoJSON。
GET /_search { "sort" : [ { "_geo_distance" : { "pin.location" : [-70, 40], "order" : "asc", "unit" : "km" } } ], "query" : { "term" : { "user" : "kimchy" } } }
Multiple reference points
例如,多个地理点可以作为包含任何geo_point格式的数组传递,例如
GET /_search { "sort" : [ { "_geo_distance" : { "pin.location" : [[-70, 40], [-71, 42]], "order" : "asc", "unit" : "km" } } ], "query" : { "term" : { "user" : "kimchy" } } }
等等。
文档的最终距离将会是文档中包含的所有点的最小/最大/平均(距离模式)距离到排序请求中给出的所有点。
Script Based Sorting
允许根据自定义脚本进行排序,这里是一个例子:
GET /_search { "query" : { "term" : { "user" : "kimchy" } }, "sort" : { "_script" : { "type" : "number", "script" : { "lang": "painless", "inline": "doc['field_name'].value * params.factor", "params" : { "factor" : 1.1 } }, "order" : "asc" } } }
Track Scores
在字段排序时,不计算分数。通过将track_scores设置为true,仍将计算和跟踪分数。
GET /_search { "track_scores": true, "sort" : [ { "post_date" : {"order" : "desc"} }, { "name" : "desc" }, { "age" : "desc" } ], "query" : { "term" : { "user" : "kimchy" } } }
Memory Considerations(内存注意事项)
排序时,相关的排序字段值将加载到内存中。这意味着每个分片应该有足够的内存来容纳它们。对于基于字符串的类型,排序的字段不应该被analyzed / tokenized。对于数字类型,如果可能,建议将类型显式设置为较窄类型(如short,integer和float)。
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.0/search-request-sort.html