我正在使用Spring Data Mongo DB并尝试执行使用Spring Data Query Method Repository,GeoJSON Near Search和QueryDSLPredicate的查询。当我提出这样的请求时:
loads/near?latitude=38.8895&longitude=-77.0353&kilometers=100&plannedStops.address.state=REEFE&page=0&size=10&sort=plannedStops.address.state,asc
Spring Data Mong DB创建以下查询,完全忽略Predicate(plannedStops.address.state = REEFE):
03:34:30.807 [http-nio-8080-exec-7] DEBUG o.s.d.m.r.query.MongoQueryCreator - Created query Query: { "plannedStops.location" : { "$nearSphere" : { $java : Point [x=38.889500, y=-77.035300] }, "$maxDistance" : 0.01567855942887398 } }, Fields: null, Sort: { "plannedStops.address.state" : -1}
03:37:00.830 [http-nio-8080-exec-4] DEBUG o.s.data.mongodb.core.MongoTemplate - find using query: { "plannedStops.location" : { "$nearSphere" : { "x" : 38.8895 , "y" : -77.0353} , "$maxDistance" : 0.01567855942887398}} fields: null for class: class Load in collection: load
当位置对象GeoJson位于Load对象上时,这没有问题,但是当它位于PlannedStops对象中时,Spring Data Mongo DB不包含谓词。所涉及的代码如下,是否有一些我缺少的东西可以让它工作?
@Repository
public interface LoadRepository extends MongoRepository<Load, String>,
QueryDslPredicateExecutor<Load> , QuerydslBinderCustomizer<QLoad> {
Long countByPlannedStopsLocationNear(Point location, Distance distance);
Page<Load> findByPlannedStopsLocationNear(Point location, Distance distance, Predicate predicate,
Pageable pageable);
}
@Document
@QueryEntity
@ApiModel
public class Load {
@Id
private String id;
private List<PlannedStop> plannedStops = new ArrayList<>();
}
@QueryEntity
@Document
@ApiModel
public class PlannedStop {
private Address address = new Address();
private BigDecimal longitude;
private BigDecimal latitude;
@JsonIgnore
@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
private GeoJsonPoint location;
}
@QueryEntity
@Document
@ApiModel
public class Address {
private String streetAddress1;
private String streetAddress2;
private String city;
private String state;
private String zipCode;
private String country;
}
Service Layer
@Override
public LoadResponse listNear(final Double longitude, final Double latitude,
final Integer kilometers, final Predicate predicate, final Pageable pageable) {
if ((longitude == null) || (latitude == null) || (kilometers == null)) {
throw new IllegalArgumentException("Longitude, Latitude, and Kilometers are missing");
}
// Client's current location
Point point = new Point(latitude, longitude);
// convert feet to miles before sending to service
Distance distance = new Distance(kilometers, Metrics.KILOMETERS);
LoadResponse loadResponse = new LoadResponse();
loadResponse.setCount(loadRepository.countByPlannedStopsLocationNear(point, distance));
loadResponse.setData(Lists
.newArrayList(loadRepository.findByPlannedStopsLocationNear(point, distance, predicate, pageable)));
return loadResponse;
}
Controller Layer
public ResponseEntity<LoadResponse> listNear(
@RequestParam(value = "longitude") final Double longitude,
@RequestParam(value = "latitude") final Double latitude,
@RequestParam(value = "kilometers") final Integer kilometers,
@QuerydslPredicate(root = Load.class) final Predicate predicate,
final Pageable pageable) {
LoadResponse data = loadService.listNear(longitude, latitude, kilometers, predicate, pageable);
if (data == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(data, HttpStatus.OK);
}