java - 如果天数差为 x 天,则 Spring MongoDB 查询文档

标签 java mongodb spring-boot criteria spring-data-mongodb

我有一个包含两个日期字段的集合,我正在尝试查询相差 15 天的所有记录:

{
   "_id" : "someid",
   "factoryNumber" : 123,
   "factoryName" : "some factory name",
   "visitType" : "audit",
   "personelId" : "somePersonel",
   "lastVisit": ISODate("2018-10-30T00:00:00.000+0000"),
   "acceptedDate" : ISODate("2018-11-16T00:00:00.000+0000")
}

现在在某些情况下 acceptedDate 将不存在,因此我需要根据当前日期对其进行评估。不完全确定如何在 spring 中编写此类查询以获得期望的结果。

    Criteria.where("acceptedDate"). 
(is 15 days past last visit or current date if last visit not present)

最佳答案

从 3.6 开始,您必须使用新运算符 $expr,它允许在匹配查询或常规查询中使用聚合表达式。

您可以创建 json 查询并将其直接作为 $expr 传递 Spring 尚不支持常规查询。

15 天 = 15 * 24 * 60 * 60 * 1000 = 1296000000 毫秒

Query query = new BasicQuery("{'$expr':{'$gte':[{'$subtract':[{'$ifNull':['$acceptedDate',{'$date':" + System.currentTimeMillis() + "}]},'$lastVisit']},1296000000]}}");
List<Document> results = mongoTemplate.find(query, Document.class);

3.4版本

如果你喜欢使用 spring mongo 方法,你必须使用投影来添加保存比较的新字段,然后是匹配操作和额外的投影来删除比较字段。不幸的是 $addFields仍然不支持,因此您必须使用 AggregationOperation 手动创建新阶段。

AggregationOperation addFields = new AggregationOperation() {
    @Override
    public Document toDocument(AggregationOperationContext aggregationOperationContext) {
        Document document = new Document("comp", Document.parse("{'$gte':[{'$subtract':[{'$ifNull':['$acceptedDate', {'$date':" + System.currentTimeMillis() + "}]},'$lastVisit']},1296000000]}}"));      
        return new Document("$addFields", document);
    }
};

Aggregation aggregation = Aggregation.newAggregation(
        addFields,
        Aggregation.match(Criteria.where("comp").is(true))
        Aggregation.project().andExclude("comp");
);

List<Document> results = mongoTemplate.aggregate(aggregation, collection name, Document.class).getMappedResults();

3.2版本

AggregationOperation redact = new AggregationOperation() {
    @Override
    public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
    Map<String, Object> map = new LinkedHashMap<>();
    map.put("if",  BasicDBObject.parse("{'$gte':[{'$subtract':[{'$ifNull':['$acceptedDate', {'$date':" + System.currentTimeMillis() + "}]},'$lastVisit']},1296000000]}}"));
    map.put("then", "$$KEEP");
    map.put("else", "$$PRUNE");
    return new BasicDBObject("$redact", new BasicDBObject("$cond", map));
};

Aggregation aggregation = Aggregation.newAggregation(redact);

List<FactoryAcceptance> results = mongoTemplate.aggregate(aggregation, FactoryAcceptance.class, FactoryAcceptance.class).getMappedResults();

关于java - 如果天数差为 x 天,则 Spring MongoDB 查询文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53871246/

相关文章:

java - 带有 JDK7 的 JAXB 问题 - com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException : 1 counts of IllegalAnnotationExceptions

java - 表中异常的 float

java - MongoDB Morphia save() 生成两个具有相同 ID 的对象

java - 在 Hibernate 中从数据库加载属性?

java - 从 SVG 文件创建非缓冲的 java.awt.Image

php - mongodb getLastError() php

mongodb - 从 Fluent Mongo 过渡到 Mongo C# 1.4 驱动程序

java - spring boot多个模块如何继承application.properties

java - Spring数据休息Bean验证国际化

java - 如何在 Spring Boot 中的组件中 Autowiring 存储库接口(interface)