【发布时间】:2014-08-14 12:06:13
【问题描述】:
我发现使用 QueryDSL 时生成的查询不适用于 mongodb,但可以用于 jpa。 该代码是 github 上一个项目的一部分。
代码:
private List<LocationUpdate> findLocationsFunctions(String deviceId, Date startDate, Date endDate) {
logger.info("findLocations:" + deviceId + "," + startDate + "," + endDate);
DeviceInfo device = deviceInfoRepository.findByDeviceId(deviceId);
if (device == null) {
throw new DataRetrievalFailureException("DeviceInfo:" + deviceId);
}
return locationUpdateRepository.findByDeviceAndLocTimeBetween(device, startDate, endDate);
}
private List<LocationUpdate> findLocationsQsl(String deviceId, Date startDate, Date endDate) {
logger.info("findLocations:" + deviceId + "," + startDate + "," + endDate);
DeviceInfo device = deviceInfoRepository.findByDeviceId(deviceId);
if (device == null) {
throw new DataRetrievalFailureException("DeviceInfo:" + deviceId);
}
List<LocationUpdate> result = new ArrayList<LocationUpdate>();
Iterable<LocationUpdate> resultSet = locationUpdateRepository
.findAll(locationUpdate.device.eq(device).and(locationUpdate.locTime.between(startDate, endDate)));
for (LocationUpdate loc : resultSet) {
result.add(loc);
}
return result;
}
public List<LocationUpdate> findLocations(String deviceId, Date startDate, Date endDate) {
return findLocationsFunctions(deviceId, startDate, endDate);
// return findLocationsQsl(deviceId, startDate, endDate);
}
在评论 findLocationsFunctions 并取消评论 findLocationsQsl 时,您将能够引发问题。 项目中的正常测试将使用嵌入式 H2 执行 JPA 代码。 您将需要访问 mondodb 才能执行 mongo 配置文件的测试。 database.properties 文件包含 mongodb url。 代码:
./gradlew test testMongo
我认为问题在于 QueryDSL 谓词在 Mongo Query 中是如何转换的。 当我最初做 mongoTemplate 时。 代码:
List<LocationUpdate> locations = mongoTemplate .find(
query(where("device").is(device).and("locTime").gte(startDate)
.and("locTime").lte(endTime)), LocationUpdate.class);
它给出了一个例外“由于 BasicDBObject 的限制,您无法添加第二个 $And”并且必须更改为:
代码:
List<LocationUpdate> locations = mongoTemplate .find(
query(where("device").is(device).andOperator(
where("locTime").gte(startDate),
where("locTime").lte(endTime))), LocationUpdate.class);
我注意到当使用 finder 方法时会呈现以下内容:
代码:
"locTime" : {
"$gt" : { "$date" : "2014-04-02T14:06:23.600Z"} ,
"$lt" : { "$date" : "2014-04-02T14:06:23.931Z"}
}
findLocationsQsl 中的代码不呈现任何与 locTime 相关的条件。
使用 Spring Data MongoDB 1.5.0 和 QueryDSL 3.3.4 进行测试
【问题讨论】:
-
不呈现任何与 locTime 相关的条件是什么意思?您是否调试过 Mongo java 驱动程序调用? Querydsl 案例中的序列化查询是什么样子的?
-
查询记录如下: 使用 Spring Data Repository findByDeviceAndLocTimeBetween find using query: { "device" : { "$ref" : "deviceInfo" , "$id" : { "$oid" : “53aead0e44aed74aa839299a”}},“locTime”:{“$gt”:{“$date”:“2014-06-28T11:54:54.910Z”},“$lt”:{“$date”:“2014- 06-28T11:54:55.142Z"}}} 使用 findAll(locationUpdate.device.eq(device).and(locationUpdate.locTime.between(startDate, endDate))) findOne 使用查询:{“deviceId”:“1234- 4567-6789"}
标签: spring-data-mongodb querydsl