问题描述
我有一个聚合管道,其中包括一个像这样的项目:
I have an aggregation pipeline which includes a project like this:
$project: {
start: {
$cond: {
if: {
$eq: ["$start", "EARLY"]
},
then: "$deltastart.start",
else: "$deltastart.end"
}
},...
},...
在mongo shell中可以正常工作.如何在Spring-Mongodb中使用Aggregation框架表达这一点?我见过ProjectionOperationBuilder,ExpressionProjectionOperationBuilder类型,但没有示例如何使用它们……有什么建议吗?
which works fine in mongo shell.How to express this using the Aggregation framework in Spring-Mongodb?I have seen ProjectionOperationBuilder, ExpressionProjectionOperationBuilder types but not an example how to use them... any suggestions?
推荐答案
如果使用当前的Spring Data版本,该版本支持 $cond
运算符通过 $project
管道,然后可以将其转换为(未测试):
If using the current Spring Data release which has support for the $cond
operator via the $project
pipeline, then this can be converted to (untested):
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
运算符,在聚合操作中,有一种解决方法是实施 AggregationOperation 接口以获取DBObject:
For Spring-Data MongoDB version which do not have support for the $cond
operator in the aggregation operation, there is a workaround which is to implement the AggregationOperation interface to take in a 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,该操作与您拥有的操作相同:
Then implement the $project
operation as a DBObject in the aggregation pipeline that is the same as the one you have:
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中使用
which you can then use in TypeAggregation:
TypedAggregation<CustomClass> aggregation = newAggregation(CustomClass.class,
new CustomProjectAggregationOperation(operation)
);
AggregationResults<CustomClass> result = mongoTemplate.aggregate(aggregation, CustomClass.class);
这篇关于如何在Spring-MongoDb聚合框架中使用$ cond操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!