spring mongodb 聚合比较两个字段并得到一列的总和

spring mongodb aggregation compare two field and get sum of one column

我有一个订单集合,orderLastStatusChangeDatetime、estimatedDeliveryDatetime 和 orderPrice 是订单集合的归档名称。我必须得到 orderPrice 的总和,其中 orderLastStatusChangeDatetime 小于或等于 estimatedDeliveryDatetime。我使用下面的查询来获取总记录...

Criteria criteria = new Criteria() {
        @Override
        public DBObject getCriteriaObject() {
            DBObject obj = new BasicDBObject();
            obj.put("$where", "this.orderLastStatusChangeDatetime <= this.estimatedDeliveryDatetime");
            return obj;
        }
    };

    Query query = new Query();


    query.addCriteria(criteria);


    totalOrder = (int) mongoTemplate.count(query,ORDERS_COLLECTION_NAME);

但我必须得到订单价格的总和。我在聚合匹配中使用了相同的标准。但它给出错误 "Command failed with error 16395: 'exception: $where is not allowed inside of a $match aggregation expression'"

您可以使用以下聚合管道。在 $project 阶段创建一个 cmp 字段以保存 orderLastStatusChangeDatetime <= estimatedDeliveryDatetime 后跟 $match 的结果,其中 cmp 等于 true$group$sum order price.

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.query.Criteria.where;

Aggregation aggregation = newAggregation(project("orderPrice").andExpression("orderLastStatusChangeDatetime <= estimatedDeliveryDatetime").as("cmp"), match(Criteria.where("cmp").is(true)), group().sum("orderPrice").as("total"));

BasicDBObject results = mongoOperations.aggregate(aggregation, ORDERS_COLLECTION_NAME, BasicDBObject.class).getUniqueMappedResult();
int totalOrder = results.getInt("total");

更新:在 1.8.5 RELEASE

中使用 AggregationExpression
Aggregation agg = newAggregation(
    project("orderPrice").and(new AggregationExpression() {
                @Override
                public DBObject toDbObject(AggregationOperationContext context) {
                    return new BasicDBObject("$lte", Arrays.<Object>asList("$orderLastStatusChangeDatetime", "$estimatedDeliveryDatetime"));
                    }
    }).as("cmp"),
    match(Criteria.where("cmp").is(true)),
    group().sum("orderPrice").as("total")
);

你可以在这里找到很多如何使用它的例子: https://www.javatips.net/api/spring-data-mongodb-master/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java