【问题标题】:Invalid Query when using QueryDSL with MongoDB在 MongoDB 中使用 QueryDSL 时查询无效
【发布时间】:2014-08-14 12:06:13
【问题描述】:

我发现使用 QueryDSL 时生成的查询不适用于 mongodb,但可以用于 jpa。 该代码是 github 上一个项目的一部分。

方法在https://github.com/corneil/spring-data-demo/blob/master/src/main/java/org/springframework/data/demo/service/LocationAndDeviceServiceImpl.java

代码: ​

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


【解决方案1】:

正如 Querydsl 问题跟踪器中所回答的那样,这看起来像是 Spring Data Mongodb 的 Querydsl 集成中的一个问题。看起来 Spring Data 对日期的序列化与默认的 Mongodb Java API 日期序列化不同。

【讨论】:

  • 完全不呈现日期条件。
猜你喜欢
  • 2017-10-31
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 2019-06-17
  • 2017-01-06
相关资源
最近更新 更多