在 MongoDB 和 Spring 中尝试使用 Pageable 查找 NearLocation 时出错
Error while trying to findNearLocation with Pageable in MongoDB and Spring
当我尝试在 Mongodb 和 spring 引导中执行可分页查找附近时,我遇到了一个奇怪的错误。我的 collection 有 5 家商店。当我使用参数调用该方法时:Page 0 和 Page Size of 5 or below 它有效。但是当我使用等于或大于商店总数的 PageSize 调用它时,我得到了这个错误。我注意到当 spring 数据 mongo 在内部调用方法 doCount 时会发生错误,但我不知道出了什么问题。
下面是我的代码和错误:
----- 型号 ----
@Document("stores")
@Getter
@Setter
@TypeAlias("Store")
@ToString(of = {"id", "name"})
@EqualsAndHashCode(of = "id")
public class Store {
public static final String DOCUMENT_INDEX_NAME = "documentIndex";
public static final int MIN_SIZE_DOCUMENT = 14;
public static final int MAX_SIZE_DOCUMENT = MIN_SIZE_DOCUMENT;
public static final int MIN_SIZE_NAME = 3;
public static final int MAX_SIZE_NAME = 200;
public Store() {
this.metaInf = new MetaInf();
}
public Store(String document, String name) {
this();
this.document = document;
this.name = name;
}
@Id
private String id;
@CNPJ(message = "{validation.store.document.cnpj}")
@NotNull(message = "{validation.store.document.notnull}")
@Size(message = "{validation.store.document.size}", min = MIN_SIZE_DOCUMENT, max = MAX_SIZE_DOCUMENT)
@Pattern(message = "{validation.store.document.pattern}", regexp = "\d{" + MIN_SIZE_DOCUMENT + "}")
@Indexed(unique = true, name = DOCUMENT_INDEX_NAME)
@Field(name = "document")
private String document;
@NotNull(message = "{validation.store.name.notnull}")
@Size(message = "{validation.store.name.size}", min = MIN_SIZE_NAME, max = MAX_SIZE_NAME)
@Field(name = "name")
private String name;
@Field(name = "address")
private Address address;
@NotNull(message = "{validation.default.metainf.notnull}")
@Field(name = "metaInf")
private MetaInf metaInf;
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString(of = {"street", "number", "district", "city", "state"})
public class Address {
public static final String LOCATION_INDEX_NAME = "locationIndex";
@Field(name = "street")
private String street;
@Field(name = "number")
private String number;
@Field(name = "district")
private String district;
@Field(name = "city")
private String city;
@Field(name = "state")
private String state;
@Field(name = "location")
@GeoSpatialIndexed(name = LOCATION_INDEX_NAME, type = GeoSpatialIndexType.GEO_2DSPHERE)
private GeoJsonPoint location;
}
------ 存储库方法(此存储库扩展 MongoRepository)------
GeoPage<Store> findByAddressLocationNear(Point point, Distance distance, Pageable pageable);
-----服务-----
@Override
public GeoPage<Store> findNearest(Point point, Distance distance, Pageable pageable) {
LOG.debug("Searching nearests from {} within distance {}, pageable: {}", point, distance, pageable);
return storeRepository.findByAddressLocationNear(point, distance, pageable);
}
@Override
public GeoPage<StoreDTO> findNearestDtos(Point point, Distance distance, Pageable pageable) {
return modelMapper.map(findNearest(point, distance, pageable), new TypeToken<GeoPage<StoreDTO>>() {}.getType());
}
-----控制器-----
@PreAuthorize("hasRole('ROLE_USER')")
@GetMapping("/nearest")
public ResponseEntity<Response<GeoPageResponse<StoreDTO>, String>> findNearest(@AuthenticationPrincipal OAuth2User user
, @Valid @RequestBody(required = true) FindNearestDTO dto) {
LOG.info("Searching nearest Stores, dto {}", dto);
GeoPage<StoreDTO> page = storeService.findNearestDtos(dto.getPointsAsGeoJsonPoint(), dto.getGeoDistance(), dto.getPageable());
return Response.ok(new GeoPageResponse<>(page));
}
----- 错误 -----
Caused by: com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'Point must only contain numeric elements' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Point must only contain numeric elements", "code": 2, "codeName": "BadValue"}
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:358) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:279) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:100) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:490) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:71) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:253) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:202) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:118) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:110) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:345) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:336) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommandWithConnection(CommandOperationHelper.java:222) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.call(CommandOperationHelper.java:208) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:583) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:205) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.AggregateOperationImpl.execute(AggregateOperationImpl.java:189) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.AggregateOperation.execute(AggregateOperation.java:300) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CountOperation.execute(CountOperation.java:254) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CountOperation.execute(CountOperation.java:61) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:170) ~[mongodb-driver-sync-4.2.3.jar:na]
at com.mongodb.client.internal.MongoCollectionImpl.executeCount(MongoCollectionImpl.java:223) ~[mongodb-driver-sync-4.2.3.jar:na]
at com.mongodb.client.internal.MongoCollectionImpl.countDocuments(MongoCollectionImpl.java:192) ~[mongodb-driver-sync-4.2.3.jar:na]
at org.springframework.data.mongodb.core.MongoTemplate.lambda$doCount(MongoTemplate.java:1131) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
... 131 common frames omitted
伙计们,我解决了这个问题。在我的控制器中,我传递了一个 GeoJsonPoint
作为参数。当我更改为 Point
时,它起作用了。
----之前----
GeoPage<StoreDTO> page = storeService.findNearestDtos(dto.getPointsAsGeoJsonPoint(), dto.getGeoDistance(), dto.getPageable());
----- 之后 -----
GeoPage<StoreDTO> page = storeService.findNearestDtos(dto.getPointsAsPoint(), dto.getGeoDistance(), dto.getPageable());
当我尝试在 Mongodb 和 spring 引导中执行可分页查找附近时,我遇到了一个奇怪的错误。我的 collection 有 5 家商店。当我使用参数调用该方法时:Page 0 和 Page Size of 5 or below 它有效。但是当我使用等于或大于商店总数的 PageSize 调用它时,我得到了这个错误。我注意到当 spring 数据 mongo 在内部调用方法 doCount 时会发生错误,但我不知道出了什么问题。
下面是我的代码和错误:
----- 型号 ----
@Document("stores")
@Getter
@Setter
@TypeAlias("Store")
@ToString(of = {"id", "name"})
@EqualsAndHashCode(of = "id")
public class Store {
public static final String DOCUMENT_INDEX_NAME = "documentIndex";
public static final int MIN_SIZE_DOCUMENT = 14;
public static final int MAX_SIZE_DOCUMENT = MIN_SIZE_DOCUMENT;
public static final int MIN_SIZE_NAME = 3;
public static final int MAX_SIZE_NAME = 200;
public Store() {
this.metaInf = new MetaInf();
}
public Store(String document, String name) {
this();
this.document = document;
this.name = name;
}
@Id
private String id;
@CNPJ(message = "{validation.store.document.cnpj}")
@NotNull(message = "{validation.store.document.notnull}")
@Size(message = "{validation.store.document.size}", min = MIN_SIZE_DOCUMENT, max = MAX_SIZE_DOCUMENT)
@Pattern(message = "{validation.store.document.pattern}", regexp = "\d{" + MIN_SIZE_DOCUMENT + "}")
@Indexed(unique = true, name = DOCUMENT_INDEX_NAME)
@Field(name = "document")
private String document;
@NotNull(message = "{validation.store.name.notnull}")
@Size(message = "{validation.store.name.size}", min = MIN_SIZE_NAME, max = MAX_SIZE_NAME)
@Field(name = "name")
private String name;
@Field(name = "address")
private Address address;
@NotNull(message = "{validation.default.metainf.notnull}")
@Field(name = "metaInf")
private MetaInf metaInf;
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString(of = {"street", "number", "district", "city", "state"})
public class Address {
public static final String LOCATION_INDEX_NAME = "locationIndex";
@Field(name = "street")
private String street;
@Field(name = "number")
private String number;
@Field(name = "district")
private String district;
@Field(name = "city")
private String city;
@Field(name = "state")
private String state;
@Field(name = "location")
@GeoSpatialIndexed(name = LOCATION_INDEX_NAME, type = GeoSpatialIndexType.GEO_2DSPHERE)
private GeoJsonPoint location;
}
------ 存储库方法(此存储库扩展 MongoRepository)------
GeoPage<Store> findByAddressLocationNear(Point point, Distance distance, Pageable pageable);
-----服务-----
@Override
public GeoPage<Store> findNearest(Point point, Distance distance, Pageable pageable) {
LOG.debug("Searching nearests from {} within distance {}, pageable: {}", point, distance, pageable);
return storeRepository.findByAddressLocationNear(point, distance, pageable);
}
@Override
public GeoPage<StoreDTO> findNearestDtos(Point point, Distance distance, Pageable pageable) {
return modelMapper.map(findNearest(point, distance, pageable), new TypeToken<GeoPage<StoreDTO>>() {}.getType());
}
-----控制器-----
@PreAuthorize("hasRole('ROLE_USER')")
@GetMapping("/nearest")
public ResponseEntity<Response<GeoPageResponse<StoreDTO>, String>> findNearest(@AuthenticationPrincipal OAuth2User user
, @Valid @RequestBody(required = true) FindNearestDTO dto) {
LOG.info("Searching nearest Stores, dto {}", dto);
GeoPage<StoreDTO> page = storeService.findNearestDtos(dto.getPointsAsGeoJsonPoint(), dto.getGeoDistance(), dto.getPageable());
return Response.ok(new GeoPageResponse<>(page));
}
----- 错误 -----
Caused by: com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'Point must only contain numeric elements' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Point must only contain numeric elements", "code": 2, "codeName": "BadValue"}
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:358) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:279) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:100) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:490) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:71) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:253) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:202) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:118) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:110) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:345) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:336) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommandWithConnection(CommandOperationHelper.java:222) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.call(CommandOperationHelper.java:208) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:583) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:205) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.AggregateOperationImpl.execute(AggregateOperationImpl.java:189) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.AggregateOperation.execute(AggregateOperation.java:300) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CountOperation.execute(CountOperation.java:254) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.operation.CountOperation.execute(CountOperation.java:61) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:170) ~[mongodb-driver-sync-4.2.3.jar:na]
at com.mongodb.client.internal.MongoCollectionImpl.executeCount(MongoCollectionImpl.java:223) ~[mongodb-driver-sync-4.2.3.jar:na]
at com.mongodb.client.internal.MongoCollectionImpl.countDocuments(MongoCollectionImpl.java:192) ~[mongodb-driver-sync-4.2.3.jar:na]
at org.springframework.data.mongodb.core.MongoTemplate.lambda$doCount(MongoTemplate.java:1131) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
... 131 common frames omitted
伙计们,我解决了这个问题。在我的控制器中,我传递了一个 GeoJsonPoint
作为参数。当我更改为 Point
时,它起作用了。
----之前----
GeoPage<StoreDTO> page = storeService.findNearestDtos(dto.getPointsAsGeoJsonPoint(), dto.getGeoDistance(), dto.getPageable());
----- 之后 -----
GeoPage<StoreDTO> page = storeService.findNearestDtos(dto.getPointsAsPoint(), dto.getGeoDistance(), dto.getPageable());