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