MongoDB - 将嵌入文档中的行解包到它们自己的列中
MongoDB - unpack rows from a embedded document into their own column
问题
所以我有一个 MongoDB 文档,看起来像这样:
Awards
:
[
{
"year": "2017",
"winners": [
{
"name": "james",
"id": 1
},
{
"name": "adam",
"id": 2
}
]
},
{
"year": "2018",
"winners": [
{
"name": "mary",
"id": 3
},
{
"name": "jane",
"id": 4
}
]
}
]
我基本上是在尝试扩大每年的获胜者,以便架构大致 (year, winner_id)
我可以稍后将其用于我计划进行的连接。像这样:
[
{
"year":"2017",
"winner_id":1
},
{
"year":"2017",
"winner_id":2
},
{
"year":"2018",
"winner_id":3
},
{
"year":"2018",
"winner_id":4
}
]
我试过的
直觉上,我正在寻找类似 $unwind
的东西,但问题是 winners
不是数组。
我试过 db.awards.aggregate({'$unwind':'$winners.id'})
但没用。 (给出空结果)
所以后来我想db.awards.aggregate({'$unwind': {'$objectToArray':'$winners.id'}})
,但也没用。 (报错)
根据 this post 我应该这样做:
db.awards.aggregate(
{ '$project': {
_id: 1,
'winners': 1
} },
{'$unwind': '$winners'},
{'$unwind': '$winners.id'}
)
但即使这样也行不通,我仍然为每个 winner
获取嵌入式文档
有什么想法吗?
你需要先$unwind
the winners
and use $replaceRoot
才能在ROOT位置
db.collection.aggregate([
{ "$unwind": "$winners" },
{ "$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$winners",
{ "year": "$year" }
]
}
}
}
])
您的数据无效JSON。假设 winners
属性很可能是一个数组。
我可以在您的聚合命令中看到另外三个问题:
- 您还应该将聚合管道作为数组传递给
aggregate
函数。
$project
的语法在聚合管道中有所不同。您没有定义应包括哪些字段。你确实定义了实际的映射
- 我不明白你为什么要解开获奖者 id。要展开的属性应该是一个数组,在您的示例中只有
winners
数组。
我觉得投影前$unwind
比较容易
db.awards.aggregate(
[
{
$unwind: { path: '$winners' }
},
{
$project: {
year: '$year',
winner_id: '$winners.id'
}
}
]
);
问题
所以我有一个 MongoDB 文档,看起来像这样:
Awards
:
[
{
"year": "2017",
"winners": [
{
"name": "james",
"id": 1
},
{
"name": "adam",
"id": 2
}
]
},
{
"year": "2018",
"winners": [
{
"name": "mary",
"id": 3
},
{
"name": "jane",
"id": 4
}
]
}
]
我基本上是在尝试扩大每年的获胜者,以便架构大致 (year, winner_id)
我可以稍后将其用于我计划进行的连接。像这样:
[
{
"year":"2017",
"winner_id":1
},
{
"year":"2017",
"winner_id":2
},
{
"year":"2018",
"winner_id":3
},
{
"year":"2018",
"winner_id":4
}
]
我试过的
直觉上,我正在寻找类似 $unwind
的东西,但问题是 winners
不是数组。
我试过
db.awards.aggregate({'$unwind':'$winners.id'})
但没用。 (给出空结果)所以后来我想
db.awards.aggregate({'$unwind': {'$objectToArray':'$winners.id'}})
,但也没用。 (报错)根据 this post 我应该这样做:
db.awards.aggregate(
{ '$project': {
_id: 1,
'winners': 1
} },
{'$unwind': '$winners'},
{'$unwind': '$winners.id'}
)
但即使这样也行不通,我仍然为每个 winner
有什么想法吗?
你需要先$unwind
the winners
and use $replaceRoot
才能在ROOT位置
db.collection.aggregate([
{ "$unwind": "$winners" },
{ "$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$winners",
{ "year": "$year" }
]
}
}
}
])
您的数据无效JSON。假设 winners
属性很可能是一个数组。
我可以在您的聚合命令中看到另外三个问题:
- 您还应该将聚合管道作为数组传递给
aggregate
函数。 $project
的语法在聚合管道中有所不同。您没有定义应包括哪些字段。你确实定义了实际的映射- 我不明白你为什么要解开获奖者 id。要展开的属性应该是一个数组,在您的示例中只有
winners
数组。
我觉得投影前$unwind
比较容易
db.awards.aggregate(
[
{
$unwind: { path: '$winners' }
},
{
$project: {
year: '$year',
winner_id: '$winners.id'
}
}
]
);