mongodb - 在同一文档中按 ID 以原子方式将对象从一个数组移动到另一个数组
问题描述
我的数据如下所示:
{
"_id": ObjectId("4d525ab2924f0000000022ad"),
"arrayField": [
{ id: 1, other: 23 },
{ id: 2, other: 21 },
{ id: 0, other: 235 },
{ id: 3, other: 765 }
],
"someOtherArrayField": []
}
给定一个嵌套对象的 ID ( 0
),我想$pull
将元素从一个数组 ( arrayField
) 中取出,并将它放到同一个文档中的$push
另一个数组 ( ) 中。someOtherArrayField
结果应如下所示:
{
"_id": ObjectId("id"),
"arrayField": [
{ id: 1, other: 23 },
{ id: 2, other: 21 },
{ id: 3, other: 765 }
],
"someOtherArrayField": [
{ id: 0, other: 235 }
]
}
我意识到我可以通过查找然后更新来完成此操作,即
db.foo.findOne({"_id": param._id})
.then((doc)=>{
db.foo.update(
{
"_id": param._id
},
{
"$pull": {"arrayField": {id: 0}},
"$push": {"someOtherArrayField": {doc.array[2]} }
}
)
})
但我正在寻找一个原子操作,例如,在伪代码中,这个:
db.foo.update({"_id": param._id}, {"$move": [{"arrayField": {id: 0}}, {"someOtherArrayField": 1}]}
有没有一种原子方法可以做到这一点,也许使用 MongoDB 4.2 的能力来指定一个更新命令的管道?那看起来怎么样?
我发现这篇文章慷慨地提供了我使用的数据,但提供的解决方案不是原子操作。MongoDB 4.2 是否可以实现原子解决方案?
解决方案
这是一个例子:
> db.baz.find()
> db.baz.insert({
... "_id": ObjectId("4d525ab2924f0000000022ad"),
... "arrayField": [
... { id: 1, other: 23 },
... { id: 2, other: 21 },
... { id: 0, other: 235 },
... { id: 3, other: 765 }
... ],
... "someOtherArrayField": []
... })
WriteResult({ "nInserted" : 1 })
function extractIdZero(arrayFieldName) {
return {$arrayElemAt: [
{$filter: {input: arrayFieldName, cond: {$eq: ["$$this.id", 0]}}},
0
]};
}
extractIdZero("$arrayField")
{
"$arrayElemAt" : [
{
"$filter" : {
"input" : "$arrayField",
"cond" : {
"$eq" : [
"$$this.id",
0
]
}
}
},
0
]
}
db.baz.updateOne(
{_id: ObjectId("4d525ab2924f0000000022ad")},
[{$set: {
arrayField: {$filter: {
input: "$arrayField",
cond: {$ne: ["$$this.id", 0]}
}},
someOtherArrayField: {$concatArrays: [
"$someOtherArrayField",
[extractIdZero("$arrayField")]
]}
}}
])
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.baz.findOne()
{
"_id" : ObjectId("4d525ab2924f0000000022ad"),
"arrayField" : [
{
"id" : 1,
"other" : 23
},
{
"id" : 2,
"other" : 21
},
{
"id" : 3,
"other" : 765
}
],
"someOtherArrayField" : [
{
"id" : 0,
"other" : 235
}
]
}
推荐阅读
- gradle - 在 Gradle 中访问不同子项目中的任务属性
- debugging - 我不断收到 ModuleNotFoundError: No module named 'Crypto' 但我安装了 pycryptodome
- python - flask-restplus API 中的自定义字段类型限制为一种类型
- java - Hbase反向扫描
- php - 如何检查按钮是否被点击后台 PrestaShop
- python - 如何从存在给定子字符串的 pandas 系列字符串中选择此类实例?
- apache - 如何设置与应用程序网关和 apache httpd 的端到端 ssl 连接?
- c# - UrlHelper.Action 没有用于 controllerName 和 controllerAction 的硬编码字符串
- elixir - 在 Phoenix Forms 中对由“inputs_form”生成的输入进行分组
- android - 不可转换的类型;无法投射 android.app.Application 错误?