在MongoDB中,在同一文档中将一个元素从一个数组移动到另一个数组

3

我有这样的数据:

{
  "_id": ObjectId("4d525ab2924f0000000022ad"),
  "array": [
    { id: 1, other: 23 },
    { id: 2, other: 21 },
    { id: 0, other: 235 },
    { id: 3, other: 765 }
  ],
  "zeroes": []
}

我想从一个数组中$pull出一个元素,并将它$push到同一文档中的第二个数组中,结果应该像这样:

{
  "_id": ObjectId("id"), 
  "array": [
    { id: 1, other: 23 },
    { id: 2, other: 21 },
    { id: 3, other: 765 }
  ],
  "zeroes": [
    { id: 0, other: 235 }
  ]
}

我意识到可以通过查找然后更新的方式来完成这个任务,即

db.foo.findOne({"_id": param._id})
.then((doc)=>{
  db.foo.update(
    {
      "_id": param._id
    },
    {
      "$pull": {"array": {id: 0}},
      "$push": {"zeroes": {doc.array[2]} }
    }
  )
})

我在想是否有一个原子函数可以实现这个。 类似于,
db.foo.update({"_id": param._id}, {"$move": [{"array": {id: 0}}, {"zeroes": 1}]}

我发现了这篇慷慨地提供了我所使用数据的帖子,但问题在4年后仍未解决。过去4年中是否已经找到了解决方案?

将元素从$pull移动到另一个数组

1个回答

3

在MongoDB中没有$move。话虽如此,最简单的解决方案是分为两个步骤:

  1. 查询文档
  2. 使用$pull$push/$addToSet创建更新

这里重要的部分是确保一切都是幂等的,即在更新的查询中包含原始数组文档。

假设有一个以下形式的文档:

{
    _id: "foo",
    arrayField: [
        {
            a: 1,
            b: 1
        },
        {
            a: 2,
            b: 1
        }
    ]
}

假设你想将 { a: 1, b: 1 } 移动到另一个字段,比如叫做 someOtherArrayField,你需要执行以下操作。
var doc = db.col.findOne({_id: "foo"});
var arrayDocToMove = doc.arrayField[0];
db.col.update({_id: "foo", arrayField: { $elemMatch: arrayDocToMove} }, { $pull: { arrayField: arrayDocToMove }, $addToSet: { someOtherArrayField: arrayDocToMove } })

我们使用$elemMatch的原因是确保我们要从数组中删除的字段自查询文档以来没有发生变化。当与$pull结合使用时,它也不是绝对必要的,但在这些情况下我通常过于谨慎。如果您的应用程序中没有并行性,并且只有一个应用程序实例,则不是绝对必要的。
现在,当我们检查结果文档时,我们会得到:
db.col.findOne()
{
        "_id" : "foo",
        "arrayField" : [
                {
                        "a" : 2,
                        "b" : 1
                }
        ],
        "someOtherArrayField" : [
                {
                        "a" : 1,
                        "b" : 1
                }
        ]
}

你能否提供一个更新的答案,利用4.2版本的指定管道到更新命令的能力 - HappyNomad
1
从4.2版本开始,你可以在单个操作中执行更新。最好更新这里的答案而不是提出新问题。 - Asya Kamsky
1
这里有一个更新的4.2答案:https://stackoverflow.com/a/57224243/431012 更好的方法是编辑/添加到这个答案,因为另一个问题是重复的。 - Asya Kamsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接