使用 Spring Data @Aggregation 搜索 MongoDB ISODate

问题描述 投票:0回答:2

我有一个连接到 MongoDB 数据库的 Spring API。我正在尝试使用 Spring 的

@Aggregation
来查找“Shipment”文档中“shipDate”晚于用户指定日期的条目。

这是我的存储库的示例:

import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ShipmentRepository extends MongoRepository<Shipment, String> {
    @Aggregation("{ '$match': { shipDate: {$gt: ISODate(?0)} } }")
    int findShippedAfterDate(String date);
}

作为

date
传递的值为 “2020-06-16”。我使用 @Aggregation 而不是 @Query,因为一旦我让这部分工作,$match 之后就会有一个 $group 操作。

似乎在

?0
中使用
ISODate()
无法正常工作并导致以下错误:

JSON 读取器需要一个字符串,但发现了“?0”

我尝试了以下语法变体:

  • shipDate: {$gt: ISODate('?0')}
  • shipDate: {$gt: ISODate('$?0')}

两者都会导致以下错误,我认为这是由于

?0
实际上没有被值替换造成的:

org.bson.json.JsonParseException:日期格式无效。

我确信问题在于

?0
没有被字符串值替换,因为当使用字符串而不是变量占位符时,查询会按预期工作:

@Aggregation("{ '$match': { shipDate: {$gt: ISODate('2020-06-16')} } }")

我犯了一个简单的语法错误吗?感谢您对此的任何帮助!

mongodb match spring-data-mongodb aggregation isodate
2个回答
0
投票

我能够通过使用

$dateToString
将存储在 MongoDB 中的 ISODate 转换为可以与用户提供的日期相匹配的字符串,然后使用
$addFields
将其添加到每个条目来实现此目的。但是,我认为这种方法可能存在以下问题:

  • 效率低下,因为它会为每个返回的条目添加一个
    dateString
    字段。

我不确定这是否会成为一个问题,因为这取决于 MongoDB 如何处理

$addFields
,然后是
$match
。如果它仅将字段添加到
$match
返回的条目中,则会更加高效。

工作

@Aggregation
示例:

@Aggregation(pipeline = {
        "{ '$addFields': { 'dateString': { $dateToString: { format: '%Y-%m-%d', date: '$shipDate'} } }  }",
        "{ '$match': { dateString: {$gte: ?0} } }" })

0
投票

我也有同样的问题,似乎在 2023 年仍然存在。@Aggregation 标记参数适用于字符串和整数,但在传递日期时会发生相同的错误。我对字符串比较解决方案没有任何运气,它给出了不可预测的结果

© www.soinside.com 2019 - 2024. All rights reserved.