mongo + spring data + aggragate sum

时间:2015-10-13 10:14:21

标签: java spring mongodb aggregation-framework

我正在寻找没有弹簧数据的解决方案。我的项目要求是没有弹簧数据。

通过mongo命令使用聚合函数计算总和,能够获得输出。但是使用弹簧数据获取异常也是如此。 示例mongo查询:

db.getCollection('events_collection').aggregate(
{ "$match" : { "store_no" : 3201 , "event_id" : 882800} },
{ "$group" : { "_id" : "$load_dt", "event_id": { "$first" : "$event_id" }, "start_dt" : { "$first" : "$start_dt" }, "count" : { "$sum" : 1 } } },
{ "$sort" : { "_id" : 1 } },
{ "$project" : { "load_dt" : "$_id", "ksn_cnt" : "$count", "event_id" : 1, "start_dt" : 1, "_id" : 0 } }
)

在java中完成同样的事情,

String json = "[ { \"$match\": { \"store_no\": 3201, \"event_id\": 882800 } }, { \"$group\": { \"_id\": \"$load_dt\", \"event_id\": { \"$first\": \"$event_id\" }, \"start_dt\": { \"$first\": \"$start_dt\" }, \"count\": { \"$sum\": 1 } } }, { \"$sort\": { \"_id\": 1 } }, { \"$project\": { \"load_dt\": \"$_id\", \"ksn_cnt\": \"$count\", \"event_id\": 1, \"start_dt\": 1, \"_id\": 0 } } ]";

BasicDBList pipeline = (BasicDBList) JSON.parse(json);

System.out.println(pipeline);

AggregationOutput output = col.aggregate(pipeline);

例外是:

com.mongodb.CommandFailureException: { "serverUsed" : "somrandomserver/10.10.10.10:27001" , "errmsg" : "exception: pipeline element 0 is not an object" , "code" : 15942 , "ok" : 0.0}

有人可以建议如何在春天使用聚合函数吗?

1 个答案:

答案 0 :(得分:1)

尝试以下(未经测试) Spring Data MongoDB aggregation 等效

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

MongoTemplate mongoTemplate = repository.getMongoTemplate();
Aggregation agg = newAggregation(
    match(Criteria.where("store_no").is(3201).and("event_id").is(882800)),
    group("load_dt")
        .first("event_id").as("event_id")
        .first("start_dt").as("start_dt")
        .count().as("ksn_cnt"),
    sort(ASC, previousOperation()),
    project("ksn_cnt", "event_id", "start_dt")
        .and("load_dt").previousOperation()     
        .and(previousOperation()).exclude()
);

AggregationResults<OutputType> result = mongoTemplate.aggregate(agg,
                                            "events_collection", OutputType.class);
List<OutputType> mappedResult = result.getMappedResults();

作为第一步,使用匹配操作过滤输入集合,该操作接受Criteria查询作为参数。

在第二步中,按"load_dt"字段对中间过滤的文档进行分组,并计算文档计数并将结果存储在新字段"ksn_cnt"中。

按照previousOperation()方法给出的前一组操作的id-reference对中间结果进行排序。

最后,在第四步中,选择上一组操作中的"ksn_cnt""event_id""start_dt"字段。请注意,"load_dt"再次隐式引用group-id字段。由于您不希望显示隐式生成的ID,因此请通过and(previousOperation()).exclude()排除上一操作中的ID。

请注意,如果您提供输入类作为 newAggregation 方法的第一个参数,MongoTemplate将从此类派生输入集合的名称。否则,如果您未指定输入类,则必须显式提供输入集合的名称。如果提供了输入类和输入集合,则后者优先。