【问题标题】:Insert or Update into Mongo using mongoose and modify inner elements while updating使用 mongoose 插入或更新到 Mongodb 并在更新时修改内部元素
【发布时间】:2018-07-02 06:54:25
【问题描述】:

假设有一个文档集合,其中 field_1 是唯一的

[
    {
       field_1: 'abc',
       field_2: 0,
       field_3: []
    }
]

我想添加另一个文档,但是field_1'abc' 相同。在这种情况下,我想增加field_2,并在更新时将元素附加到field_3。如果field_1 不同,请创建另一个文档。

处理此类查询的最佳方法是什么?我的第一个想法是搜索,如果没有找到文档,然后插入,或者有没有更好的方法?这种方法的问题是,如果我一次插入多个文档,我不能有效地使用“搜索,如果没有找到文档,则插入”方法。

【问题讨论】:

  • 这一切的用例是什么?

标签: node.js mongodb mongoose


【解决方案1】:

Mongoose 现在通过 findOneAndUpdate(调用 MongoDB findAndModify)本机支持此功能。

upsert = true 选项会在对象不存在时创建它。默认为 false。

MyModel.findOneAndUpdate(
    {foo: 'bar'}, // find a document with that filter
    modelDoc, // document to insert when nothing was found
    {upsert: true, new: true, runValidators: true}, // options
    function (err, doc) { // callback
        if (err) {
            // handle error
        } else {
            // handle document
        }
    }
);

【讨论】:

  • 这并没有解决多个文档被更新或更新的问题。
  • 基于过滤器,如果满足条件,则更新它,否则为单个文档创建一个新文档。如果是多个文档,您可以使用 findAndModify
  • findAndModify的文档
  • 我想到的是,MyModel.findOneAndUpdate( {foo: {$in:bars}}, // 找到一个带有该过滤器的文档 modelDoc, // 没有找到时要插入的文档 {upsert : true, new: true, runValidators: true}, // 选项函数 (err, doc) { // 回调 if (err) { // 处理错误 } else { // 处理文档 } } );这个问题->它不会更新多个文档。只有一个。并且使用 $in-> 不包括查询的字段。您如何建议使用 findAndModify?
  • 在它的文档中,你可以更新multiple document,应该这样做
【解决方案2】:

如果field_1 的唯一性是由唯一索引强制执行的,则可以使用一种乐观锁定。

首先你尝试更新:

db.collection.update(
    {
       field_1: 'abc'
    },
    {
       $inc: {field_2: 1},
       $push: {field_3: 'abc'},
    }
);

并检查操作结果 - 如果更新了 1 个文档,则无需更多操作。否则,它是第一个具有 field_1 == 'abc' 的文档,因此您尝试插入它:

db.collection.insert(
    {
       field_1: 'abc',
       field_2: 0,
       field_3: []
    }
);

并捕获错误。如果没有错误,则不需要更多操作。否则有并发插入,需要再重复一次更新查询。

【讨论】:

  • 使用 field_1 时你会如何做同样的事情:{$in:['abc','def','ghi','jkl'] },所以假设 'ghi' 和 'jkl'不在那里,我需要插入 def 和 ghi。如果更新了一定数量的文档,您如何确定哪些文档已更新,哪些未更新,以便我可以批量插入剩余的'ghi'和'jkl'
  • 对不起,我没听懂。 field_1:{$in:['abc','def','ghi','jkl'] }, 来自哪里?正如您最初的问题 field_1 是文档的唯一标识符,因此更新查询中的唯一条件是完全匹配此字符串。如果你有 4 个文件,你可以一个一个地做。
  • 由你决定。 for 循环是一种选择,是的。我没有得到回调部分。如果你问回调一般是如何工作的,那就太宽泛了。如果您对回调有一些特殊问题,请发布带有明确问题陈述的问题。
猜你喜欢
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 2015-10-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
相关资源
最近更新 更多