【问题标题】:How to update a field using its previous value in MongoDB/Mongoose如何使用 MongoDB/Mongoose 中的先前值更新字段
【发布时间】:2017-10-01 21:15:09
【问题描述】:

例如,我有一些看起来像这样的文档:

{
    id: 1
    name: "foo"
}

我想将另一个string 附加到当前的name 字段值。

我使用 Mongoose 尝试了以下操作,但没有成功:

Model.findOneAndUpdate({ id: 1 }, { $set: { name: +"bar" } }, ...);

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    如果这仍然相关,我有 MongoDB 4.2 的解决方案。

    我的"project" 文档的"projectDeadline" 字段为Array 类型时遇到了同样的问题(["2020","12","1"])

    使用 Robo3T,我使用 SRV 链接连接到我的 MongoDB Atlas 数据库。然后执行以下代码,它对我有用。

    初始文件:

    {
      _id             : 'kjnolqnw.KANSasdasd',
      someKey         : 'someValue',
      projectDeadline : ['2020','12','1']
    }
    

    CLI 命令:

    db
    .getCollection('mainData')
    .find({projectDeadline: {$not: {$eq: "noDeadline"}}})
    .forEach((doc) => {
    
        var deadline = doc.projectDeadline;
        var deadlineDate = new Date(deadline);
    
        db
        .mainData
        .updateOne({
            _id: doc._id}, 
            {"$set": 
                {"projectDeadline": deadlineDate}
            }
        )}
    );
    

    生成的文档:

    {
      _id             : 'kjnolqnw.KANSasdasd',
      someKey         : 'someValue',
      projectDeadline : '2020-12-01 21:00:00.000Z'
    }
    

    【讨论】:

      【解决方案2】:

      您无法引用要更新的文档的值,因此您需要一个查询来检索文档,另一个查询来更新它。自 2016 年以来,OPEN 状态下似乎有一个 feature request。

      如果您有一个包含如下文档的集合:

      { "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
      

      使用 MongoDB shell,您可以执行以下操作:

      db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
          doc.name = "foo-" + doc.name;
      
          db.test.save(doc);
      });
      

      文档将按预期更新:

      { "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
      

      注意.snapshot() 调用。 这样可以确保查询不会多次返回文档,因为由于文档大小的增长,中间的写入操作会移动它。

      将此应用于您的 Mongoose 示例,如 this official example 中所述:

      Cat.findById(1, (err, cat) => {
          if (err) return handleError(err);
      
          cat.name = cat.name + "bar";
      
          cat.save((err, updatedCat) => {
              if (err) return handleError(err);
      
              ...
          });
      });
      

      值得一提的是,聚合框架中有一个$concat 运算符,但遗憾的是您不能在update 查询中使用它。

      无论如何,根据您的需要,您可以将其与$out 运算符一起使用,以将聚合结果保存到新集合中。

      同样的例子,你会这样做:

      db.test.aggregate([{
          $match: { name: "bar" }
      }, {
          $project: { name: { $concat: ["foo", "-", "$name"] }}
      }, {
          $out: "prefixedTest"
      }]);
      

      将创建一个新集合prefixedTest,其中包含如下所示的文档:

      { "_id" : ObjectId("XXX"), "name": "foo-bar" }
      

      作为参考,关于同一主题还有另一个有趣的问题值得一读:Update MongoDB field using value of another field

      【讨论】:

        猜你喜欢
        • 2017-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多