Elasticsearch 7.10.1导入数据时触发Illegal Argument Exception异常
你的错误根源其实是Elasticsearch 7.x版本对文档类型的废弃,加上导入命令里的小失误导致的,和你预先定义的映射配置无关,下面具体拆解:
为什么会出现这个错误?
在Elasticsearch 7.10.1中,官方已经彻底废弃了多文档类型的概念,每个索引只能使用默认的_doc类型(或者省略类型,底层默认用_doc)。你在导入数据时用了test_write_v1/test这个路径,其中test是你自定义的文档类型,这会触发Elasticsearch自动为这个不存在的类型生成新的映射——它会把startLocationPoint推断成普通的object类型,而你预先创建的索引里已经把这个字段定义为geo_point(一种特殊的object类型),两者冲突就抛出了"can't merge a non object mapping [startLocationPoint] with an object mapping"的错误。
另外,你原来的curl命令里的JSON数据没有用单引号包裹,shell可能会解析出错,这也是潜在的问题。
修复步骤
1. 修正导入数据的命令
把路径里的test替换成默认的_doc,同时给JSON数据加上单引号避免shell解析问题:
curl -sS -H "Content-Type: application/json" -XPOST localhost:9200/test_write_v1/_doc?pretty -d '{ "id": "000f4930-b168-3560-b691-78e757524494", "created": "2021-09-15T18:26:43.713Z", "startLocationPoint": { "lat": 34.803279, "lon": -119.633169 }, "startAltitudeMeters": 30000.0 }'
也可以直接省略类型部分,效果是一样的:
curl -sS -H "Content-Type: application/json" -XPOST localhost:9200/test_write_v1?pretty -d '{ "id": "000f4930-b168-3560-b691-78e757524494", "created": "2021-09-15T18:26:43.713Z", "startLocationPoint": { "lat": 34.803279, "lon": -119.633169 }, "startAltitudeMeters": 30000.0 }'
2. 验证索引映射是否正确
如果不确定索引是否正确创建,可以用下面的命令查看当前映射:
curl -sS localhost:9200/test_write_v1/_mapping?pretty
你应该能看到startLocationPoint的类型明确是geo_point。
3. 若映射已被污染,重新创建索引
如果之前的错误导入已经导致索引映射混乱,建议先删除旧索引,再重新创建:
# 删除索引 curl -XDELETE localhost:9200/test_write_v1 # 重新创建索引(同样注意用单引号包裹JSON) curl -sS -H "Content-Type: application/json" -XPUT localhost:9200/test_write_v1?pretty -d '{ "settings" : { "index" : { "number_of_shards" : 1, "number_of_replicas" : 0 } }, "mappings": { "properties": { "id": { "type": "text", "fields": { "raw": { "type": "keyword" } } }, "created": { "type": "date" }, "startAltitudeMeters": { "type": "float" }, "startLocationPoint": { "type": "geo_point" } } } }'
补充说明
你对geo_point的配置是完全正确的,Elasticsearch确实支持lat+lon的对象格式,只要确保导入时使用正确的文档类型(或者省略类型),就能正常导入数据。
内容的提问来源于stack exchange,提问作者jencoston

