Elasticsearch Spring Boot报错:地理距离排序找不到location字段映射
解决Elasticsearch地理距离排序报错问题
问题背景
调用nearest3接口查询最近3个地点时出现错误,接口接收经纬度参数(示例:{"lat": 51.53266860674158,"lon": -0.1593017578125}),核心逻辑是基于地理距离排序获取Top3结果。
接口代码
@PostMapping("/nearest3") List<ResultData> nearest3(@RequestBody RequestData requestData) { GeoPoint location = new GeoPoint(requestData.getLat(), requestData.getLon()); Sort sort = Sort.by(new GeoDistanceOrder("location", location).withUnit("km")); List<SearchHit<FoodPOI>> searchHits; if (StringUtils.hasText(requestData.getName())) { searchHits = repository.searchTop3ByName(requestData.getName(), sort); } else { searchHits = repository.searchTop3By(sort); } return toResultData(searchHits); }
报错信息
org.elasticsearch.ElasticsearchException: Elasticsearch exception [type=illegal_argument_exception, reason=failed to find mapper for [location] for geo distance based sort] at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:496) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.ElasticsearchException.fromXContent(ElasticsearchException.java:407) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:437) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.ElasticsearchException.fromXContent(ElasticsearchException.java:407) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:437) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.ElasticsearchException.failureFromXContent(ElasticsearchException.java:603) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:169) ~[elasticsearch-7.6.2.jar:7.6.2] at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1793) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2] at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1770) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2] at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1527) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2] at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1484) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2] at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1454) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2] at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:970) ~[elasticsearch-rest-high-level-client-7.6.2.jar:7.6.2] at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.lambda$count$9(ElasticsearchRestTemplate.java:263) ~[spring-data-elasticsearch-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.execute(ElasticsearchRestTemplate.java:359) ~[spring-data-elasticsearch-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.count(ElasticsearchRestTemplate.java:263) ~[spring-data-elasticsearch-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery.execute(ElasticsearchPartQuery.java:102) ~[spring-data-elasticsearch-4.0.3.RELEASE.jar:4.0.3.RELEASE] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
错误原因
报错核心提示failed to find mapper for [location] for geo distance based sort,说明Elasticsearch索引中location字段未被正确映射为geo_point类型,导致无法基于该字段执行地理距离排序操作。
解决步骤
1. 修正实体类字段映射
找到FoodPOI实体类,确保location字段使用@GeoPointField注解,且字段类型为GeoPoint:
import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.geo.GeoPoint; public class FoodPOI { // 其他字段... @GeoPointField private GeoPoint location; // 对应的getter和setter方法 }
2. 重新生成索引映射
- 自动创建索引:若项目使用Spring Data Elasticsearch自动创建索引,需先删除已存在的旧索引,再重启服务让框架重新生成带有正确
geo_point映射的索引。 - 手动创建索引:执行以下Elasticsearch API命令手动创建索引(替换
your_index_name为实际索引名):
PUT /your_index_name { "mappings": { "properties": { "location": { "type": "geo_point" }, // 其他字段的映射配置... } } }
3. 验证映射正确性
执行以下命令检查location字段的映射类型:
GET /your_index_name/_mapping/field/location
返回结果应显示type为geo_point,表示映射配置正确。
4. 检查Repository方法
确认searchTop3ByName和searchTop3By方法正确接收并应用排序参数,未对location字段的排序逻辑做错误覆盖或处理。
内容的提问来源于stack exchange,提问作者emr1717
相关产品推荐
相关产品推荐

