如何 promote/pull 子字段在 mongo 聚合管道中向上一级
How to promote/pull a child field up one level in mongo aggregation pipeline
我有一个看起来像这样的集合:
[
{
_id: ObjectId("6255a889fb63822bd51b0356"),
answers: {
"6255a889fb63822bd51b0326": {
value: ObjectId("6255a889fb63822bd51b0329"),
},
"6255a889fb63822bd51b032a": {
value: [
ObjectId("6255a889fb63822bd51b0321"),
ObjectId("6255a889fb63822bd51b032d")
],
},
"6255a889fb63822bd51b032e": {
value: 2,
comment: "hello",
}
},
createdAt: ISODate("2022-03-12T17:27:53.890Z")
}
]
我从
开始我的管道
{
$project: {
_id: 0,
answers: { $objectToArray: "$answers" },
date: { $dateToString: { format: dateFormat, date: "$createdAt" } },
},
},
得到这样的结果:
[
{
answers: [
{
k: '6255a9a60fd8f862f4bd287f',
v: {
value: new ObjectId("6255a9a60fd8f862f4bd2882"),
_id: new ObjectId("6255a9a60fd8f862f4bd28b2")
}
},
{
k: '6255a9a60fd8f862f4bd2883',
v: {
value: [
new ObjectId("6255a9a60fd8f862f4bd287a"),
new ObjectId("6255a9a60fd8f862f4bd2886")
],
_id: new ObjectId("6255a9a60fd8f862f4bd28b3")
}
},
{
k: '6255a9a60fd8f862f4bd2887',
v: {
value: 2,
comment: 'hello',
_id: new ObjectId("6255a9a60fd8f862f4bd28b4")
}
}
],
date: '2022-03-12'
}
]
我想拉起 value
并将 v
替换为 value
所以我最终得到如下所示的结果。我在想也许在 $objectToArray 的第一步中有一些方法可以做到这一点?或者之后我还需要另一个步骤吗?
[
{
answers: [
{
k: '6255a9a60fd8f862f4bd287f',
v: new ObjectId("6255a9a60fd8f862f4bd2882")
},
{
k: '6255a9a60fd8f862f4bd2883',
v: [
new ObjectId("6255a9a60fd8f862f4bd287a"),
new ObjectId("6255a9a60fd8f862f4bd2886")
]
},
{
k: '6255a9a60fd8f862f4bd2887',
v: 2
}
],
date: '2022-03-12'
}
]
您只需要再 $map
即可获得您想要的形式。
db.collection.aggregate([
{
$project: {
_id: 0,
answers: {
"$map": {
"input": {
$objectToArray: "$answers"
},
"as": "a",
"in": {
k: "$$a.k",
v: "$$a.v.value"
}
}
},
date: {
$dateToString: {
format: "%Y-%m-%d",
date: "$createdAt"
}
}
}
}
])
这是Mongo playground供您参考。
我有一个看起来像这样的集合:
[
{
_id: ObjectId("6255a889fb63822bd51b0356"),
answers: {
"6255a889fb63822bd51b0326": {
value: ObjectId("6255a889fb63822bd51b0329"),
},
"6255a889fb63822bd51b032a": {
value: [
ObjectId("6255a889fb63822bd51b0321"),
ObjectId("6255a889fb63822bd51b032d")
],
},
"6255a889fb63822bd51b032e": {
value: 2,
comment: "hello",
}
},
createdAt: ISODate("2022-03-12T17:27:53.890Z")
}
]
我从
开始我的管道{
$project: {
_id: 0,
answers: { $objectToArray: "$answers" },
date: { $dateToString: { format: dateFormat, date: "$createdAt" } },
},
},
得到这样的结果:
[
{
answers: [
{
k: '6255a9a60fd8f862f4bd287f',
v: {
value: new ObjectId("6255a9a60fd8f862f4bd2882"),
_id: new ObjectId("6255a9a60fd8f862f4bd28b2")
}
},
{
k: '6255a9a60fd8f862f4bd2883',
v: {
value: [
new ObjectId("6255a9a60fd8f862f4bd287a"),
new ObjectId("6255a9a60fd8f862f4bd2886")
],
_id: new ObjectId("6255a9a60fd8f862f4bd28b3")
}
},
{
k: '6255a9a60fd8f862f4bd2887',
v: {
value: 2,
comment: 'hello',
_id: new ObjectId("6255a9a60fd8f862f4bd28b4")
}
}
],
date: '2022-03-12'
}
]
我想拉起 value
并将 v
替换为 value
所以我最终得到如下所示的结果。我在想也许在 $objectToArray 的第一步中有一些方法可以做到这一点?或者之后我还需要另一个步骤吗?
[
{
answers: [
{
k: '6255a9a60fd8f862f4bd287f',
v: new ObjectId("6255a9a60fd8f862f4bd2882")
},
{
k: '6255a9a60fd8f862f4bd2883',
v: [
new ObjectId("6255a9a60fd8f862f4bd287a"),
new ObjectId("6255a9a60fd8f862f4bd2886")
]
},
{
k: '6255a9a60fd8f862f4bd2887',
v: 2
}
],
date: '2022-03-12'
}
]
您只需要再 $map
即可获得您想要的形式。
db.collection.aggregate([
{
$project: {
_id: 0,
answers: {
"$map": {
"input": {
$objectToArray: "$answers"
},
"as": "a",
"in": {
k: "$$a.k",
v: "$$a.v.value"
}
}
},
date: {
$dateToString: {
format: "%Y-%m-%d",
date: "$createdAt"
}
}
}
}
])
这是Mongo playground供您参考。