You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elastic Search按文本字段排序报错illegal_argument_exception排查

Elasticsearch按嵌套对象字段排序报错的解决方法

索引配置

为Elasticsearch的Products配置了如下索引:

{
    "settings": {
        "index": {
            "number_of_shards": 3,
            "number_of_replicas": 0
        }
    },
    "mappings": {
        "properties": {
            "name": {
                "fields": {
                    "original": {
                        "type": "keyword"
                    }
                },
                "type": "text",
                "fielddata": true,
                "analyzer": "portuguese"
            },
            "product_data": {
                "type": "object"
            }
        }
    }
}

数据写入操作

通过以下请求写入数据(响应为201 created):
请求URL:http://127.0.0.1:9200/product2/_update/IMOB01
请求体:

{
    "doc": {
        "name":"Test",
        "product_data": {
            "symbol": "IMOB01",
            "release_date": "2013-01-01T00:00:00"
        }
    },
    "doc_as_upsert": true
}

问题现象

执行搜索时,按name字段排序正常,但尝试按product_data.symbol字段排序时收到错误。

搜索请求URL:localhost:9200/product/_search
请求体:

{
    "from": 0,
    "size": 50,
    "query": {
        "bool": {
            "must": {
                "match": {
                    "product_data.symbol": "imob01"
                }
            }
        }
    },
    "sort": [
         { "product_data.symbol": {"order": "asc", "unmapped_type" : "text"}}
    ]
}

错误响应:

{
    "error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [product_data.symbol] in order to load field data by uninverting the inverted index. Note that this can use significant memory."
            }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [
            {
                "shard": 0,
                "index": "product",
                "node": "PfwDOAwzTZm63IHq_rt1TA",
                "reason": {
                    "type": "illegal_argument_exception",
                    "reason": "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [product_data.symbol] in order to load field data by uninverting the inverted index. Note that this can use significant memory."
                }
            }
        ],
        "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [product_data.symbol] in order to load field data by uninverting the inverted index. Note that this can use significant memory.",
            "caused_by": {
                "type": "illegal_argument_exception",
                "reason": "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [product_data.symbol] in order to load field data by uninverting the inverted index. Note that this can use significant memory."
            }
        }
    },
    "status": 400
}

将product_data设为object类型是因为部分产品有不同字段,但给product_data设置fielddata:true并未解决问题。


问题原因

  1. 索引名称不匹配:写入数据的索引是product2,但搜索的是product索引,这会导致搜索的索引中可能没有对应数据或映射,需先确认索引名称是否正确。
  2. fielddata设置位置错误:product_data是object类型,fielddata是text字段的专属属性,给object类型设置fielddata:true不会传递到内部的product_data.symbol字段。Elasticsearch自动将product_data.symbol映射为text类型,而text字段默认不支持排序/聚合,必须针对该字段本身开启fielddata或设置keyword子字段。

解决方案

方案1:添加keyword子字段(推荐)

对于symbol这类标识性字段,使用keyword类型排序/聚合更高效,且内存占用低。需要修改索引映射并重新索引数据:

  1. 修改索引映射(以product2为例):
PUT /product2/_mapping
{
    "properties": {
        "product_data": {
            "properties": {
                "symbol": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}
  1. 重新索引现有数据(确保新字段生效)
  2. 搜索时使用product_data.symbol.keyword排序:
{
    "from": 0,
    "size": 50,
    "query": {
        "bool": {
            "must": {
                "match": {
                    "product_data.symbol": "imob01"
                }
            }
        }
    },
    "sort": [
         { "product_data.symbol.keyword": {"order": "asc"}}
    ]
}

方案2:开启product_data.symbol的fielddata(不推荐)

如果不想重新索引,可以直接给product_data.symbol字段开启fielddata,但会占用较多堆内存,不建议在生产环境使用:

PUT /product2/_mapping
{
    "properties": {
        "product_data": {
            "properties": {
                "symbol": {
                    "type": "text",
                    "fielddata": true
                }
            }
        }
    }
}

之后即可使用原字段进行排序,但需监控内存使用情况。


内容的提问来源于stack exchange,提问作者Thiago Pelissari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:50:54