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将作为文档返回的一部分一起返回。
order 有以下取值:
取值 | 说明 |
---|---|
asc | 递增 |
desc | 递减 |
当是_score
排序时默认按照desc
, 其他默认使用 asc
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"}}
]
}
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 用于对字段没有取值的文档的排序,missing 可以取值为_last, _first, 或者自定义值 (自定义会用于缺值文档的排序).默认是 _last.
例如:
GET /_search
{
"sort" : [
{ "price" : {"missing" : "_last"} }
],
"query" : {
"term" : { "product" : "chocolate" }
}
}
注意
嵌套对象的内部对象不匹配nested_filter 那么就会使用missing.
默认情况下,如果对没有mapping的字段查询会失败. unmapped_type允许你无视没有mapping的字段并且不用它们排序 。unmapped_type的取值决定使用什么排序mapping。
例如:
GET /_search
{
"sort" : [
{ "price" : {"unmapped_type" : "long"} }
],
"query" : {
"term" : { "product" : "chocolate" }
}
}
如果查询的任一文档price没有 mapping没有值,Elasticsearch 将会把它的mapping 当成long处理