我有两个文档:比如Foo
和Qux
。
Foo
看起来像这样:
{
"_id": ObjectId("5c52bb1af9b7bb512458a6d1"),
"name": "Foo 1",
"description": "This is a Foo",
"bars": [
{
"name": "Bar 1",
"description": "This is a Bar",
"qux": ObjectId("5c3f3d59d45cca2d1860bb4e")
},
{
"name": "Bar 2",
"description": "This is a Bar",
"qux": ObjectId("5c3f3d59d45cca2d1860bb4e")
}
]
}
Qux
如下:
{
"_id": ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name": "Qux 1",
"description": "This is a Qux"
}
我的目标是将相应的Qux
嵌入到Foo.bars
的每个元素中,如下所示:
[{
"_id": ObjectId("5c52bb1af9b7bb512458a6d1"),
"name": "Foo 1",
"description": "This is a Foo",
"bars": [
{
"name": "Bar 1",
"description": "This is a Bar",
"qux": {
"_id": ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name": "Qux 1",
"description": "This is a Qux"
}
},
{
"name": "Bar 2",
"description": "This is a Bar document",
"qux": {
"_id": ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name": "Qux 1",
"description": "This is a Qux"
}
}
]
}]
我尝试了以下汇总:
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(Criteria.where("_id").is(id)),
Aggregation.unwind("bars", true),
Aggregation.lookup("qux", "bars.qux", "_id", "bars.qux"),
Aggregation.project("_id", "name", "description")
.and("bars.qux").arrayElementAt(0).as("bars.qux")
.and("bars.name").as("bars.name")
.and("bars.description").as("bars.description"),
Aggregation.group("_id")
.push("bars").as("bars")
.first("name").as("name")
.first("description").as("description")
);
但是由于这一行IllegalArgumentException
,它抛出了.push("bars").as("bars")
:
java.lang.IllegalArgumentException: Invalid reference 'bars'!
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:100) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:72) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDocument(GroupOperation.java:421) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:55) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.aggregation.Aggregation.toPipeline(Aggregation.java:645) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.AggregationUtil.createPipeline(AggregationUtil.java:95) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.doAggregate(MongoTemplate.java:2070) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:2046) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1945) ~[spring-data-mongodb-2.1.3.RELEASE.jar:2.1.3.RELEASE]
如果我在不执行分组操作的情况下执行了聚合,那么它可以工作,但是我为每个bar元素得到一个Foo,并且每个Foo包含一个不同的bar元素,这是我放开它们以来的期望值:
[{
"_id": ObjectId("5c52bb1af9b7bb512458a6d1"),
"name": "Foo 1",
"description": "This is a Foo",
"bars": {
"name": "Bar 1",
"description": "This is a Bar",
"qux": {
"_id": ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name": "Qux 1",
"description": "This is a Qux"
}
}
},
{
"_id": ObjectId("5c52bb1af9b7bb512458a6d1"),
"name": "Foo 1",
"description": "This is a Foo",
"bars": {
"name": "Bar 2",
"description": "This is a Bar",
"qux": {
"_id": ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name": "Qux 1",
"description": "This is a Qux"
}
}
}]
有没有办法实现我的目标?
答案 0 :(得分:1)
不用$unwind
就可以得到所需的输出。一旦$lookup
,我们就可以$map
和$indexOfArray
来$arrayElemAt
加入数组并使用$mergeObjects
db.foo.aggregate([
{$lookup: {from : "qux", localField : "bars.qux", foreignField : "_id", as : "join"}},
{$addFields: {bars: {$map : {input : "$bars", as : "b", in : {$mergeObjects :[ "$$b", {qux: {$arrayElemAt : ["$join", {$indexOfArray: ["$join._id", "$$b.qux"]}]}}]}}}}},
{$project: {join:0}}
]).pretty()
输出
{
"_id" : ObjectId("5c52bb1af9b7bb512458a6d1"),
"name" : "Foo 1",
"description" : "This is a Foo",
"bars" : [
{
"name" : "Bar 1",
"description" : "This is a Bar",
"qux" : {
"_id" : ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name" : "Qux 1",
"description" : "This is a Qux"
}
},
{
"name" : "Bar 2",
"description" : "This is a Bar",
"qux" : {
"_id" : ObjectId("5c3f3d59d45cca2d1860bb4e"),
"name" : "Qux 1",
"description" : "This is a Qux"
}
}
]
}