使用带有Spring-data-mongodb的$ cond运算符

时间:2014-02-25 17:15:37

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

我希望汇总以下数据

{
   "user": "user1",
   "error": true 
}
{
   "user": "user2",
   "error": false
}
{
   "user": "user1",
   "error": false
}

{
     "_id": "user1",
     "errorCount": 1,
     "totalCount": 2
},
{
     "_id": "user2",
     "errorCount": 0,
     "totalCount": 1
}

使用$ cond运算符,可以使用以下方法实现:

$group: {
    _id: "$user",
    errorCount : { "$sum" : {"$cond" : ["$error", 1, 0]}},
    totalCount : { "$sum" : 1 }
}

但是,由于我使用的是尚未支持$ cond的Spring-data-mongodb(从1.3.4-RELEASE开始),我无法做到这一点。

有没有办法在没有$ cond的情况下进行相同的聚合?

2 个答案:

答案 0 :(得分:7)

感谢Neil Lunn的建议,我设法让$ cond使用spring-data的聚合支持。为此,您必须实现AggregationOperation接口以接收DBObject。

public class DBObjectAggregationOperation implements AggregationOperation {
  private DBObject operation;

  public DBObjectAggregationOperation (DBObject operation) {
    this.operation = operation;
  }

  @Override
  public DBObject toDBObject(AggregationOperationContext context) {
    return context.getMappedObject(operation);
  }
}

然后你就可以在TypeAggregation中正常使用它了:

DBObject operation = (DBObject)JSON.parse ("your pipleline here...");
TypedAggregation<UserStats> aggregation = newAggregation(User.class,
    new DBObjectAggregationOperation(operation)
    );
AggregationResults<UserStats> result = mongoTemplate.aggregate(aggregation, UserStats.class); 

此方法允许您使用框架中尚未定义的任何聚合运算符。但是,它也绕过了弹簧数据的验证,应谨慎使用 如果您希望通过框架正确支持$ cond运算符,请投票:https://jira.springsource.org/browse/DATAMONGO-861

答案 1 :(得分:3)

即使Spring数据中没有“功能接口”,您也不会受此限制。 (顺便说一句,提出一个JIRA)

只需获取本机表单并在管道中使用BasicDBObject类型。所以原则上:

    DBCollection myCollection = mongoOperation.getCollection("collection");

    <result cast> = myCollection.aggregate(<pipeline here>);

Spring数据为您提供抽象,但禁止使用 native 驱动程序函数。它实际上让你访问者使用它们,正如我在上面演示的那样。