ElasticSearch日期范围查询报错原因及正确查询方法咨询
问题原因与解决方案
核心问题
报错NumberFormatException: For input string: "09-02-2016"的本质是:你的start_time字段在ElasticSearch索引的映射中是数字类型(如long/integer),但你用日期字符串去查询,ES尝试将字符串转为数字失败,导致查询报错。你对ES日期存储的理解有误——ES仅对映射为date类型的字段会自动转为时间戳存储,若字段映射为数字类型,ES会直接按数字处理。
第一步:验证字段映射
先执行以下命令确认start_time的实际映射类型:
GET /accidents/_mapping/field/start_time
两种场景的解决方案
场景1:start_time确实存储为时间戳(数字类型)
如果字段值是毫秒/秒级时间戳,需将你的目标日期转为对应时间戳再查询。例如09-02-2016(假设格式为MM-DD-YYYY)对应的毫秒时间戳是1472774400000,修改后的查询语句:
{ "query": { "bool": { "must": [ { "match": { "message": "start_time" } }, { "range": { "start_time": { "gte": 1472774400000, "lte": 1472774400000 } } } ] } } }
场景2:start_time应映射为日期类型(映射错误)
ES无法直接修改已有字段的映射,需重新创建索引并迁移数据:
- 创建新索引,指定
start_time为日期类型并匹配你的日期格式:
PUT /accidents_new { "mappings": { "properties": { "start_time": { "type": "date", "format": "MM-dd-yyyy" }, "message": { "type": "text" } // 复制原索引其他字段的映射 } } }
- 迁移原索引数据到新索引:
POST _reindex { "source": { "index": "accidents" }, "dest": { "index": "accidents_new" } }
- (可选)替换原索引别名,保持应用查询逻辑不变:
DELETE /accidents PUT /accidents/_alias/accidents_new
完成后即可用你最初的日期字符串格式查询。
内容的提问来源于stack exchange,提问作者Santiago Makcimovich
相关产品推荐
相关产品推荐

