Spring Data MongoDB - 聚合方法

Sen*_* SP 4 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]}
                          }

        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

Bla*_*ven 6

Spring mongo目前不支持:

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

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

所以第二种情况是在这种情况下会破坏聚合辅助函数的使用.你可以通过先做一个来解决这个问题$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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

    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
                                ))
                            )
                        )
                    )
            )
    );
Run Code Online (Sandbox Code Playgroud)

并且与$group您定义的阶段完全一致地构建管道.