Spring Data MongoDB - 聚合方法

时间:2015-09-19 05:24:40

标签: java mongodb aggregation-framework spring-data-mongodb

有谁知道如何使用Spring-data将以下聚合函数转换为java代码?

db.myCollection.aggregate([
    {$match:{"status" : {$in:["WORKING","UNASSIGNED"]}}},
    {$group:{
            _id:{
                "status":"$status",
                "queue":"$queueName"
             },
             "count":{$sum:1},
             "oldest":{$min:"$queueTime"},
             "slow":{$sum:{$cond:[
                                {$lte: ["$queueServiceTs", new Date()]},
                                        1,
                                        0]}
                          }

        }
    }
]);

1 个答案:

答案 0 :(得分:6)

Spring mongo目前不支持:

  1. 带有自定义键名的复合聚合_id,当然您可以接受defualt字段名称翻译

  2. $cond中使用$sum操作或任何表达式,因为它只支持映射字段。

  3. 所以第二种情况是在这种情况下会破坏聚合辅助函数的使用。您可以先通过$project来解决这个问题,但这需要额外的执行阶段来影响性能。

    但你可以做的是创建自己的抽象类,它在标准构建器函数中工作,但允许你用标准对象构建管道阶段:

    public class CustomGroupOperation implements AggregationOperation {
        private DBObject operation;
    
        public CustomGroupOperation (DBObject operation) {
            this.operation = operation;
        }
    
        @Override
        public DBObject toDBObject(AggregationOperationContext context) {
            return context.getMappedObject(operation);
        }
    }
    

    然后您可以将它与标准构建器一起使用,如下所示:

        Aggregation aggregation = newAggregation(
                new CustomGroupOperation(
                        new BasicDBObject("$group",
                            new BasicDBObject("_id",
                                new BasicDBObject("status","$status")
                                    .append("queue","$queueName")
                            )
                            .append("count",new BasicDBObject("$sum",1))
                            .append("oldest", new BasicDBObject("$min","$queueTime"))
                            .append("slow",
                                new BasicDBObject("$sum",
                                    new BasicDBObject("$cond",Arrays.asList(
                                        new BasicDBObject("$lte",Arrays.asList(
                                            "$queueServiceTs",
                                            new Date()
                                        )),
                                        1,
                                        0
                                    ))
                                )
                            )
                        )
                )
        );
    

    这就构建了一个$group阶段的管道,就像你定义的一样。