这有点令人困惑。
我正在尝试$group
aggregatation
和grouping
的结果我创建新字段,其中包含两个不同字段的结合。嗯。实际上我不愿意分享数据库的结构并让你感到困惑。但描述并不是解释性的。
所以我们走了。
学生收藏
{id: "1", school: "georgia tech"}
大学收藏
{name: "georgia tech" , state: "Georgia" , city: "Atlanta"}
我想得到什么?我想得到
{id: 1, name: "georgia tech" , place: "Georgia_Atlanta"}
我做了什么来实现这个目标?
db.student.aggregate([
{$match: {"id": "1"}},
{$lookup: {from: "university" , localField: "school" , foreignField: "name", as: "document"}},
{$group: {_id: "$id", name: {$push: "$school"}, place: {$push: {$concat: ["$document.state" , "_" , "$document.city"]}}}}
])
但这会引发错误;
assert: command failed: {
"ok" : 0,
"errmsg" : "$concat only supports strings, not Array",
"code" : 16702
}
与此同时;
db.student.aggregate([
{$match: {"id": "1"}},
{$lookup: {from: "university" , localField: "school" , foreignField: "name", as: "document"}},
{$group: {_id: "$id", name: {$push: "$school"}, place: {$push: "$document.state" }}}
])
返回为;
{ "_id" : "1", "name" : [ "georgia tech" ], "place" : [ [ "Georgia" ] ] }
问题在于汇总state
和city
字段。
所以这里的问题又来了。如何连结document.state
,_
和document.city
?
答案 0 :(得分:5)
$lookup
返回一个数组,因此您需要使用$arrayElemAt
运算符展平它(如果它有一个元素)或 $unwind
(如果它有多个元素)。因此,最后,您应该能够运行以下管道以获得所需的结果:
db.student.aggregate([
{ "$match": { "id": "1" } },
{
"$lookup": {
"from": "university",
"localField": "school",
"foreignField": "name",
"as": "document"
}
},
{
"$project": {
"id": 1,
"university": { "$arrayElemAt": [ "$document", 0 ] }
}
},
{
"$project": {
"id": 1,
"name": "$university.name",
"place": { "$concat": ["$university.state", "_", "$university.city"] }
}
}
])
答案 1 :(得分:1)
我不知道确切的用例,但是如果你需要使用GroupBy,这是工作版本。否则,chridam使用更简单的方法:
db.student.aggregate([
{$match: {"id": "1"}},
{$lookup: {from: "university" , localField: "school" , foreignField: "name", as: "document"}},
{$group: {_id: "$id", name: {$first: "$school"}, tempplace: {$first: "$document" }}},
{$unwind: "$tempplace"},
{$project: {id: 1, name: 1, place: {$concat: ["$tempplace.state", "_", "$tempplace.city"]}}}
])