英文:
How do I merge two Arrays of objects into one Set of objects in MongoDB?
问题
以下是facet阶段后的结果:
{
directComputers: [
{
_id: ObjectId('6139f794f6a0af371900dbfh'),
name: MyComputer_1
},
{
_id: ObjectId('6319bd1540b41d1a35717a16'),
name: MyComputer_2
}
],
indirectComputers: [
{
_id: ObjectId('6319bd1540b41d1a35717a16'),
name: MyComputer_2
},
{
_id: ObjectId('61f39f8ae2daa732deff6d90'),
name: MyComputer_3
}
]
}
我想要将两个数组中的对象添加到一个集合中(以避免重复),然后展开它们,以便得到每个对象的单独文档,如下所示:
{
_id: ObjectId('6139f794f6a0af371900dbfh'),
name: MyComputer_1
}
____
{
_id: ObjectId('6319bd1540b41d1a35717a16'),
name: MyComputer_2
}
____
{
_id: ObjectId('61f39f8ae2daa732deff6d90'),
name: MyComputer_3
}
如何实现这个目标?
英文:
I have the following result after a facet stage:
{
directComputers: [
{
_id: ObjectId('6139f794f6a0af371900dbfh'),
name: MyComputer_1
},
{
_id: ObjectId('6319bd1540b41d1a35717a16'),
name: MyComputer_2
}
],
indirectComputers: [
{
_id: ObjectId('6319bd1540b41d1a35717a16'),
name: MyComputer_2
},
{
_id: ObjectId('61f39f8ae2daa732deff6d90'),
name: MyComputer_3
}
]
I'm trying to add the objects from both arrays into a set (to avoid duplicates), and then unwind so I end up with one separate document for each object.
Like this:
{
_id: ObjectId('6139f794f6a0af371900dbfh'),
name: MyComputer_1
}
{
_id: ObjectId('6319bd1540b41d1a35717a16'),
name: MyComputer_2
}
{
_id: ObjectId('61f39f8ae2daa732deff6d90'),
name: MyComputer_3
}
How do I achieve that?
答案1
得分: 1
假设你的两个数组中的对象完全相同(即_id
和name
都相同,且没有其他字段),你可以使用$setUnion
构建并集。然后使用$unwind
和$replaceRoot
:
db.collection.aggregate([
{
"$project": {
allComputers: {
"$setUnion": [
"$directComputers",
"$indirectComputers"
]
}
}
},
{
"$unwind": "$allComputers"
},
{
"$replaceRoot": {
"newRoot": "$allComputers"
}
}
])
如果你希望根据某个关键字段(比如这里的_id
)进行比较,你可以使用$reduce
构建并集:
db.collection.aggregate([
{
"$project": {
allComputers: {
"$reduce": {
"input": "$indirectComputers",
"initialValue": "$directComputers",
"in": {
"$cond": {
"if": {
"$in": [
"$$this._id",
"$$value._id"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
}
}
}
}
}
},
{
"$unwind": "$allComputers"
},
{
"$replaceRoot": {
"newRoot": "$allComputers"
}
}
])
英文:
Assuming the objects inside your 2 arrays are completely identical(i.e. both _id
and name
is the same and contains no other fields), you can use $setUnion
to construct the union. Then $unwind
and $replaceRoot
db.collection.aggregate([
{
"$project": {
allComputers: {
"$setUnion": [
"$directComputers",
"$indirectComputers"
]
}
}
},
{
"$unwind": "$allComputers"
},
{
"$replaceRoot": {
"newRoot": "$allComputers"
}
}
])
If you would rather compare with some key field, says _id
in this case, you can use $reduce
to construct the union.
db.collection.aggregate([
{
"$project": {
allComputers: {
"$reduce": {
"input": "$indirectComputers",
"initialValue": "$directComputers",
"in": {
"$cond": {
"if": {
"$in": [
"$$this._id",
"$$value._id"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
}
}
}
}
}
},
{
"$unwind": "$allComputers"
},
{
"$replaceRoot": {
"newRoot": "$allComputers"
}
}
])
答案2
得分: 0
如果您希望结果展开,可以执行以下操作:
db.collection.aggregate([
{$project: {
_id: 0,
data: {$concatArrays: ["$directComputers", "$indirectComputers"]}
}},
{$unwind: "$data"},
{$group: {_id: "$data._id", name: {$first: "$data.name"}}}
])
请在[playground示例](https://mongoplayground.net/p/veDbvtjh9Tk)上查看其运行方式
另一个更通用的选项是(适用于不需要 `$unwind` 的情况):
db.collection.aggregate([
{$project: {
_id: 0,
data: {$setUnion: ["$directComputers", "$indirectComputers"]}
}},
{$unwind: "$data"},
{$replaceRoot: {newRoot: "$data"}}
])
请在[playground示例](https://mongoplayground.net/p/T6HtKhdtmHc)上查看其运行方式
英文:
Since you want the results unwinded you can do:
db.collection.aggregate([
{$project: {
_id: 0,
data: {$concatArrays: ["$directComputers", "$indirectComputers"]}
}},
{$unwind: "$data"},
{$group: {_id: "$data._id", name: {$first: "$data.name"}}}
])
See how it works on the playground example
Another option is which is more generic (for cases where $unwind
is not needed):
db.collection.aggregate([
{$project: {
_id: 0,
data: {$setUnion: ["$directComputers", "$indirectComputers"]}
}},
{$unwind: "$data"},
{$replaceRoot: {newRoot: "$data"}}
])
See how it works on the playground example
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论