gpt4 book ai didi

mongodb - 为什么在使用 GeoJsonPoint 执行 nearSphere 查询时会出现 CodecConfigurationException?

转载 作者:行者123 更新时间:2023-12-05 07:01:21 25 4
gpt4 key购买 nike

这个问题一直困扰着我。因此,我有一个 UserModel,我使用 org.springframework.data.mongodb.core.geo.GeoJsonPoint 对象存储用户的最后已知坐标,该对象转换为

"lastKnownCoordinates": {
"type": "Point",
"coordinates": [77.596503, 12.966267]
}

我有一个映射到 ExcursionsModel 对象的游览集合。每个游览都有一个地理定位属性,该属性使用 GeoJsonPoint 规范存储其位置,如下所示:

"geolocation": {
"coordinates": [73.739978, 15.606188],
"type": "Point"
}

现在,当用户尝试添加附近过滤器以获取指定距离内的短途旅行时,我在查询对象 (org.springframework.data.mongodb .core.query.Query) 像这样

if (userRequest.getDistInMeters() != null) {
query.addCriteria(Criteria.where("geolocation")
.nearSphere(userModel.getLastKnownCoordinates())
.maxDistance(userRequest.getDistInMeters())
);
}

从技术上讲,这应该转化为以下内容:

...
"geolocation" : {
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ 77.596503, 12.966267 ]
},
$maxDistance: 10000
}
}...

(如果 distInMeters = 10000)

但是,我宁愿翻译成:

...
"geolocation" : {
"$nearSphere" : {
"$geometry" : {
"$java" : Point [x=-3.703790, y=40.416775]
}
}
}...

请注意,GeoJsonPoint 的转换不正确。我也得到以下异常

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.springframework.data.mongodb.core.geo.GeoJsonPoint.

输出的完整记录:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.springframework.data.mongodb.core.geo.GeoJsonPoint.] with root cause
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.springframework.data.mongodb.core.geo.GeoJsonPoint.
at org.bson.internal.CodecCache.getOrThrow(CodecCache.java:57)
at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:64)
at org.bson.internal.ChildCodecRegistry.get(ChildCodecRegistry.java:52)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:197)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:212)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:195)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:212)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:195)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:212)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:154)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
at org.bson.BsonDocumentWrapper.getUnwrapped(BsonDocumentWrapper.java:195)
at org.bson.BsonDocumentWrapper.isEmpty(BsonDocumentWrapper.java:115)
at com.mongodb.internal.operation.DocumentHelper.putIfNotNullOrEmpty(DocumentHelper.java:43)
at com.mongodb.internal.operation.FindOperation.getCommand(FindOperation.java:792)
at com.mongodb.internal.operation.FindOperation.access$1600(FindOperation.java:77)
at com.mongodb.internal.operation.FindOperation$4.create(FindOperation.java:858)
at com.mongodb.internal.operation.CommandOperationHelper.executeCommandWithConnection(CommandOperationHelper.java:219)
at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:631)
at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:625)
at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:462)
at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:625)
at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:77)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:190)
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135)
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92)
at com.example.comercial.backend.dao.ExcursionDao.getAllExcursions(ExcursionsDao.java:140)
at com.example.comercial.backend.service.ExcursionsService.getAllExcursions(ExcursionsService.java:70)
at com.example.comercial.backend.controller.ExcursionsController.getAllExcursions(ExcursionsController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:289)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

ExcursionsDao 类中抛出异常的代码片段:

...
FindIterable<Document> findIterable = mongoTemplate.getCollection("excursions")
.find(query.getQueryObject())
.skip(pageable.getPageSize() * (pageable.getPageNumber() - 1))
.limit(pageable.getPageSize());

if (userRequest.getOrderBy() != null && userRequest.getSortOrder() != null) {
if (userRequest.getSortOrder().getSortOrder().equals(SortOrder.ASC.getSortOrder())) {
findIterable.sort(Sorts.ascending(userRequest.getOrderBy().getOrderBy()));
} else {
findIterable.sort(Sorts.descending(userRequest.getOrderBy().getOrderBy()));
}
}

ArrayList<ExcursionModel> excursionModelList = new ArrayList<>();

for (Document document : findIterable) { // Line 140 where the exception is thrown
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
excursionModelList.add(objectMapper.convertValue(document, ExcursionModel.class));
}

我使用的是 mongo 连接的默认值,它实际上是用 GeoJsonCodecProvider 初始化的。

来自 MongoClientSettings 类:

public final class MongoClientSettings {
private static final CodecRegistry DEFAULT_CODEC_REGISTRY =
fromProviders(asList(new ValueCodecProvider(),
new BsonValueCodecProvider(),
new DBRefCodecProvider(),
new DBObjectCodecProvider(),
new DocumentCodecProvider(new DocumentToDBRefTransformer()),
new IterableCodecProvider(new DocumentToDBRefTransformer()),
new MapCodecProvider(new DocumentToDBRefTransformer()),
new GeoJsonCodecProvider(),
new GridFSFileCodecProvider(),
new Jsr310CodecProvider(),
new BsonCodecProvider()));

我尝试过哪些无效的替代方案

1. 我为 GeoJsonPoint 对象编写了以下序列化程序(取 self 忘记的 SO 答案)

public class GeoJsonPointSerializer extends JsonSerializer<GeoJsonPoint> {

@Override
public void serialize(final GeoJsonPoint value, final JsonGenerator gen, final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeStringField("type", value.getType());
gen.writeArrayFieldStart("coordinates");
gen.writeObject(value.getCoordinates());
gen.writeEndArray();
gen.writeEndObject();
}

}

并将其用于 ExcursionsModel 中的地理位置属性,如下所示

@JsonSerialize(using = GeoJsonPointSerializer.class)
@GeoSpatialIndexed(name = "geoIndex", type = GeoSpatialIndexType.GEO_2DSPHERE)
private GeoJsonPoint geolocation;

2.我创建了一个 CodecRegistry 实例,并向其中添加了 PointCodec 以及来自 MongoClientSettings 的默认编解码器注册表,然后初始化了 FilterIterable 使用此编解码器注册表的类。

CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromCodecs(new PointCodec(MongoClientSettings.getDefaultCodecRegistry()))
);

FindIterable<Document> findIterable = mongoTemplate.getCollection("excursions").withCodecRegistry(codecRegistry)
.find(query.getQueryObject())
.skip(pageable.getPageSize() * (pageable.getPageNumber() - 1))
.limit(pageable.getPageSize());

我在所有情况下都抛出相同的异常。

注意:我知道 StackOverflow 上的其他问题看起来与这个问题相似,但它们的目标与我想要实现的目标有点不同。我想使用查询对象来保持查询动态。

我正在使用的依赖项:

spring-boot-starter-data-mongodb | 2.3.3.发布

mongodb 核心驱动程序 | 4.0.5

Spring 数据 mongdb | 3.0.3.发布

最佳答案

dis 你是这样创建集合索引的吗?

db.user.createIndex({ geolocation : "2dsphere" } );

请运行此命令,然后重试。

关于mongodb - 为什么在使用 GeoJsonPoint 执行 nearSphere 查询时会出现 CodecConfigurationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63886374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com