【问题标题】:How to use $cond operation in Spring-MongoDb aggregation frameworkSpring-MongoDb聚合框架中如何使用$cond操作
【发布时间】:2015-05-25 00:32:31
【问题描述】:

我有一个聚合管道,其中包括这样的项目:

$project: {
  start: {
    $cond: {
      if: {
        $eq: ["$start", "EARLY"]
      },
      then: "$deltastart.start",
      else: "$deltastart.end"
    }
  },...
},...

在 mongo shell 中运行良好。 如何使用 Spring-Mongodb 中的聚合框架来表达这一点? 我看过 ProjectionOperationBuilder、ExpressionProjectionOperationBuilder 类型,但没有看到如何使用它们的示例……有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    如果使用通过 $project 管道支持 $cond 运算符的当前 Spring Data 版本,则可以将其转换为(未经测试):

    import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
    import static org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.*;
    import org.springframework.data.mongodb.core.query.Criteria;
    
    Cond condOperation = ConditionalOperators.when(Criteria.where("start").is("EARLY"))
                                        .thenValueOf("deltastart.start")
                                        .otherwise("deltastart.end");
    
    Aggregation agg = newAggregation(project().and(condOperation).as("start"));
    AggregationResults<MyClass> results = mongoTemplate.aggregate(agg, MyClass.class); 
    List<MyClass> myList = results.getMappedResults();
    

    对于在聚合操作中不支持 $cond 运算符的 Spring-Data MongoDB 版本,有一个解决方法是实现 AggregationOperation 接收 DBObject 的接口:

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

    然后将$project 操作实现为聚合管道中的DBObject,与您拥有的相同:

    DBObject operation = (DBObject) new BasicDBObject(
        "$project", new BasicDBObject(
             "start", new BasicDBObject(
                    "$cond", new Object[]{
                            new BasicDBObject(
                                "$eq", new Object[]{ "$start", "EARLY"}
                            ),
                            "$deltastart.start",
                            "$deltastart.end"
                     }
               )
         )
    );
    

    然后您可以在 TypeAggregation 中使用它:

    TypedAggregation<CustomClass> aggregation = newAggregation(CustomClass.class,
        new CustomProjectAggregationOperation(operation)
    );
    AggregationResults<CustomClass> result = mongoTemplate.aggregate(aggregation, CustomClass.class); 
    

    【讨论】:

    • 你能展示DBObjectAggregationOperation类的实现吗?
    • 打错字了,应该是CustomProjectAggregationOperation,更正了。
    • 你能告诉我哪个spring数据版本支持“applyCondition”
    • spring-data-mongodb-2.0.8.RELEASE AggregationOperation 不幸不再暴露 toDBObject
    【解决方案2】:

    我添加了相同的问题并在 Google 上搜索,这是我找到的第一个结果,所以我想为未来的读者补充一下,自 1.10 RC1 版本以来,此功能现在可用,ConditionalOperators.Cond 类。

    您可以阅读 JavaDoc here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 2021-06-15
      • 1970-01-01
      相关资源
      最近更新 更多