问题描述
我正在尝试从 Spring Framework 项目的 MongoDB 中的数组中获取元素.
I am trying to fetch an element from an array in the MongoDB in my Spring Framework project.
我找到了MongoDB shell的解决方案,但我不知道如何通过Spring.data.core.aggregation实现它,Spring不支持聚合运算符@addFields之一.
I have find the solution for MongoDB shell, but I do not know how to implement it by Spring.data.core.aggregation, one of aggregation operator @addFields is not supported by Spring.
谁能告诉我如何替换这个@addField 或如何以另一种方式实现它?非常感谢!!!
Could anyone tell me how to replace this @addField or how to implement in it another way? Thank you so much!!!
MongoDB 示例数据:
MongoDB sample data:
{ "_id" : 15, "items" : [ { "columns" : [ { "title" : "hhh", "value" : 10 }, { "title" : "hahaha", "value" : 20 } ] }, { "columns" : [ { "title" : "hiii", "value" : 50 } ] } ] }
预期结果:
{ "_id" : 15, "items" : [ { "columns" : [ { "title" : "hahaha", "value" : 20 } ] }, { "columns" : [] } ]
}
MongoDB Shell的解决方案:
The solution for MongoDB Shell:
let value = "hahaha"; db.coll.aggregate([ { "$addFields": { "items": { "$map": { "input": "$items", "as": "item", "in": { "columns": { "$filter": { "input": "$$item.columns", "as": "elt", "cond": { "$eq": [ "$$elt.title", value ] } } } } } } } } ])
MongoDB 版本:3.4.1
春季版:1.4.3
MongoDB version: 3.4.1
Spring version: 1.4.3
推荐答案
您可以尝试以下方法,但您需要使用 1.8.5 版本.
You can try the following but you'll need to use 1.8.5 version.
Aggregation aggregation = newAggregation( project("_id").and(new AggregationExpression() { @Override public DBObject toDbObject(AggregationOperationContext aggregationOperationContext) { DBObject filter = new BasicDBObject("input", "$$item.columns").append("as", "elt").append("cond", new BasicDBObject("$eq", Arrays.<Object>asList("$$elt.title", "hahaha"))); DBObject map = new BasicDBObject("input", "$items").append("as", "item").append("in", filter); return new BasicDBObject("$map", map); } }).as("items") );
在 1.10.0.RC1 中添加了对一些 Mongo3.2 聚合运算符的支持.如果您可以更新到发布候选版本,您可以使用以下版本.我在 RC 中找不到 $addFields 阶段,所以保留了 $project 阶段.
The support for some of Mongo3.2 aggregation operators were added in 1.10.0.RC1. If you are okay with updating to release candidate version you can use the below version. I couldn't find $addFields stage in the RC so kept the $project stage.
Aggregation aggregation = newAggregation( project("_id") .and(mapItemsOf("items").as("item").andApply(filter("item.columns") .as("elt") .by(valueOf("elt.title").equalToValue("hahaha")) )).as("items") );
静态导入:
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter; import static org.springframework.data.mongodb.core.aggregation.ComparisonOperators.Eq.valueOf; import static org.springframework.data.mongodb.core.aggregation.VariableOperators.mapItemsOf;