欢迎光临
我们一直在努力

Elasticsearch 排序类型全解析:支持类型+实战示例+生产避坑

Elasticsearch 排序类型全解析:支持类型+实战示例+生产避坑

    • 前言
    • 一、核心概念:Elasticsearch 排序基础
      • 1.1 排序原理
      • 1.2 排序关键字
      • 1.3 排序执行流程图
      • 1.4 重要规则
    • 二、Elasticsearch 支持的排序类型(全)
      • 2.1 排序类型总览
    • 三、排序类型实战示例
      • 3.1 排序类型:数字类型排序(最常用)
      • 3.2 排序类型:日期类型排序
      • 3.3 排序类型:关键字字典排序
      • 3.4 排序类型:文档ID排序
      • 3.5 排序类型:相关性分数排序
      • 3.6 排序类型:地理位置距离排序(Geo)
      • 3.7 排序类型:脚本自定义排序
      • 3.8 排序类型:嵌套字段排序(Nested)
    • 四、多字段组合排序
    • 五、常见错误与避坑指南
      • 5.1 text 类型字段不能排序
      • 5.2 排序性能低
      • 5.3 中文排序乱序
    • 六、排序类型总结表
    • 七、总结(核心3条)
      • 总结

🌺The Begin🌺点点关注,收藏不迷路🌺

前言

在使用 Elasticsearch 进行搜索时,排序(Sort) 是必不可少的功能。ES 支持对数字、日期、文本、地理位置、字典等多种类型进行排序,但不同字段类型的排序规则、使用方式完全不同,错误使用会导致排序失效、报错或性能低下。

本文详细讲解 Elasticsearch 支持哪些排序类型,每种排序都附带清晰定义、使用场景、可直接运行的示例,并包含流程图、注意事项,完全符合 CSDN 发布标准,适用于 ES 7.x/8.x 全版本。


一、核心概念:Elasticsearch 排序基础

1.1 排序原理

Elasticsearch 默认按相关性分数(_score)降序排序。 手动排序时,会根据字段原始值进行排序,而非分词后的值。

1.2 排序关键字

  • asc:升序(从小到大)
  • desc:降序(从大到小)

1.3 排序执行流程图

#mermaid-svg-aArWIEUqx1CKpfXE{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aArWIEUqx1CKpfXE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aArWIEUqx1CKpfXE .error-icon{fill:#552222;}#mermaid-svg-aArWIEUqx1CKpfXE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aArWIEUqx1CKpfXE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aArWIEUqx1CKpfXE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aArWIEUqx1CKpfXE .marker.cross{stroke:#333333;}#mermaid-svg-aArWIEUqx1CKpfXE svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aArWIEUqx1CKpfXE p{margin:0;}#mermaid-svg-aArWIEUqx1CKpfXE .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-aArWIEUqx1CKpfXE .cluster-label text{fill:#333;}#mermaid-svg-aArWIEUqx1CKpfXE .cluster-label span{color:#333;}#mermaid-svg-aArWIEUqx1CKpfXE .cluster-label span p{background-color:transparent;}#mermaid-svg-aArWIEUqx1CKpfXE .label text,#mermaid-svg-aArWIEUqx1CKpfXE span{fill:#333;color:#333;}#mermaid-svg-aArWIEUqx1CKpfXE .node rect,#mermaid-svg-aArWIEUqx1CKpfXE .node circle,#mermaid-svg-aArWIEUqx1CKpfXE .node ellipse,#mermaid-svg-aArWIEUqx1CKpfXE .node polygon,#mermaid-svg-aArWIEUqx1CKpfXE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aArWIEUqx1CKpfXE .rough-node .label text,#mermaid-svg-aArWIEUqx1CKpfXE .node .label text,#mermaid-svg-aArWIEUqx1CKpfXE .image-shape .label,#mermaid-svg-aArWIEUqx1CKpfXE .icon-shape .label{text-anchor:middle;}#mermaid-svg-aArWIEUqx1CKpfXE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aArWIEUqx1CKpfXE .rough-node .label,#mermaid-svg-aArWIEUqx1CKpfXE .node .label,#mermaid-svg-aArWIEUqx1CKpfXE .image-shape .label,#mermaid-svg-aArWIEUqx1CKpfXE .icon-shape .label{text-align:center;}#mermaid-svg-aArWIEUqx1CKpfXE .node.clickable{cursor:pointer;}#mermaid-svg-aArWIEUqx1CKpfXE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aArWIEUqx1CKpfXE .arrowheadPath{fill:#333333;}#mermaid-svg-aArWIEUqx1CKpfXE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aArWIEUqx1CKpfXE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aArWIEUqx1CKpfXE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aArWIEUqx1CKpfXE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aArWIEUqx1CKpfXE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aArWIEUqx1CKpfXE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aArWIEUqx1CKpfXE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aArWIEUqx1CKpfXE .cluster text{fill:#333;}#mermaid-svg-aArWIEUqx1CKpfXE .cluster span{color:#333;}#mermaid-svg-aArWIEUqx1CKpfXE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aArWIEUqx1CKpfXE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aArWIEUqx1CKpfXE rect.text{fill:none;stroke-width:0;}#mermaid-svg-aArWIEUqx1CKpfXE .icon-shape,#mermaid-svg-aArWIEUqx1CKpfXE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aArWIEUqx1CKpfXE .icon-shape p,#mermaid-svg-aArWIEUqx1CKpfXE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aArWIEUqx1CKpfXE .icon-shape .label rect,#mermaid-svg-aArWIEUqx1CKpfXE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aArWIEUqx1CKpfXE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aArWIEUqx1CKpfXE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aArWIEUqx1CKpfXE :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

指定排序字段+规则

ES提取字段原始值

按asc/desc排序

返回排序后结果

展示有序数据

1.4 重要规则

  • text 类型字段不能直接排序(会报错)
  • 排序必须使用 keyword、数字、日期、布尔 类型
  • 多字段排序按书写顺序执行

  • 二、Elasticsearch 支持的排序类型(全)

    2.1 排序类型总览

  • 数字类型排序(integer、long、float、double)
  • 日期类型排序(date)
  • 关键字精确值排序(keyword)
  • 文档ID排序(_id)
  • 相关性分数排序(_score)
  • 地理位置距离排序(Geo Distance)
  • 脚本自定义排序(Script)
  • 嵌套字段排序(Nested)
  • 下面逐一详细说明。


    三、排序类型实战示例

    3.1 排序类型:数字类型排序(最常用)

    标题格式:排序类型:数字类型排序(integer/long/float)

    • 适用字段:价格、年龄、销量、序号
    • 支持:升序、降序
    • 示例:按价格降序

    GET /product/_search
    {
    "sort": [
    {
    "price": {
    "order": "desc"
    }
    }
    ]
    }


    3.2 排序类型:日期类型排序

    标题格式:排序类型:日期类型排序(date)

    • 适用字段:创建时间、更新时间、发布时间
    • 示例:按创建时间最新在前

    GET /article/_search
    {
    "sort": [
    {
    "create_time": {
    "order": "desc"
    }
    }
    ]
    }


    3.3 排序类型:关键字字典排序

    标题格式:排序类型:keyword 字典排序

    • 适用字段:用户名、分类、标签
    • 必须是 keyword 类型,text 类型不能排序
    • 示例:按用户名 A-Z 升序

    GET /user/_search
    {
    "sort": [
    {
    "username.keyword": {
    "order": "asc"
    }
    }
    ]
    }


    3.4 排序类型:文档ID排序

    标题格式:排序类型:文档ID _id 排序

    • 按文档ID字典序排序

    GET /user/_search
    {
    "sort": [
    {
    "_id": {
    "order": "asc"
    }
    }
    ]
    }


    3.5 排序类型:相关性分数排序

    标题格式:排序类型:相关性分数 _score 排序

    • 默认排序方式
    • 搜索匹配度越高,分数越高

    GET /product/_search
    {
    "query": {
    "match": {
    "name": "手机"
    }
    },
    "sort": [
    {
    "_score": {
    "order": "desc"
    }
    }
    ]
    }


    3.6 排序类型:地理位置距离排序(Geo)

    标题格式:排序类型:地理位置距离排序(geo_distance)

    • 适用场景:附近的店、离我最近、地理排序
    • 示例:按离目标坐标距离由近到远排序

    GET /shop/_search
    {
    "sort": [
    {
    "_geo_distance": {
    "location": {
    "lat": 39.9,
    "lon": 116.4
    },
    "order": "asc",
    "unit": "km"
    }
    }
    ]
    }


    3.7 排序类型:脚本自定义排序

    标题格式:排序类型:脚本自定义排序(Script)

    • 自定义计算规则后排序
    • 示例:价格 * 2 后排序

    GET /product/_search
    {
    "sort": {
    "_script": {
    "type": "number",
    "script": {
    "lang": "painless",
    "source": "doc['price'].value * 2"
    },
    "order": "desc"
    }
    }
    }


    3.8 排序类型:嵌套字段排序(Nested)

    标题格式:排序类型:嵌套字段排序(nested)

    • 对 nested 类型子字段排序
    • 示例:按子对象中的价格排序

    GET /order/_search
    {
    "sort": [
    {
    "items.price": {
    "order": "desc",
    "nested": {
    "path": "items"
    }
    }
    }
    ]
    }


    四、多字段组合排序

    标题格式:排序类型:多字段组合排序

    • 先按销量降序,销量相同按价格升序

    GET /product/_search
    {
    "sort": [
    { "sales": { "order": "desc" } },
    { "price": { "order": "asc" } }
    ]
    }


    五、常见错误与避坑指南

    5.1 text 类型字段不能排序

    • 错误:Fielddata is disabled on text fields
    • 原因:text 分词后无法排序
    • 解决:使用 .keyword 后缀

    5.2 排序性能低

    • 原因:排序字段未使用 doc_values
    • 解决:使用 keyword、数字、日期类型

    5.3 中文排序乱序

    • 解决:使用 keyword 类型 + 拼音分词器

    六、排序类型总结表

    排序类型字段类型典型场景
    数字排序 integer/long/float 价格、销量、年龄
    日期排序 date 时间、创建时间
    字典排序 keyword 用户名、分类
    ID排序 _id 文档ID
    相关性排序 _score 搜索匹配度
    地理位置排序 geo_point 附近店铺
    脚本排序 任意 自定义计算排序
    嵌套排序 nested 子字段排序

    七、总结(核心3条)

  • Elasticsearch 支持 8 种排序类型,覆盖绝大多数业务场景
  • text 不能排序,必须使用 keyword、数字、日期
  • 排序语法统一:sort: [{字段: {order: asc/desc}}]

  • 总结

  • 数字、日期、keyword 是最常用的三种排序类型
  • text 禁止排序,必须用 keyword 子字段
  • 地理位置、脚本、嵌套排序满足高级需求
  • 多字段排序按书写顺序执行
  • 在这里插入图片描述

    🌺The End🌺点点关注,收藏不迷路🌺

    赞(0)
    未经允许不得转载:171主机测评 » Elasticsearch 排序类型全解析:支持类型+实战示例+生产避坑
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址