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

没有更多推荐了,返回首页