【问题标题】:Delete a key from a MongoDB document using Mongoose使用 Mongoose 从 MongoDB 文档中删除一个键
【发布时间】:2011-05-28 01:55:30
【问题描述】:

我正在使用 Mongoose 库通过 node.js 访问 MongoDB

有没有办法从文档中删除密钥?即不只是将值设置为 null,而是将其删除?

User.findOne({}, function(err, user){
  //correctly sets the key to null... but it's still present in the document
  user.key_to_delete = null;

  // doesn't seem to have any effect
  delete user.key_to_delete;

  user.save();
});

【问题讨论】:

标签: mongodb node.js mongoose document-database


【解决方案1】:

在 mongo 语法中删除一些您需要执行以下操作的键:

{ $unset : { field : 1} }

在 Mongoose 似乎也一样。

编辑

查看this 示例。

【讨论】:

  • 你能澄清这个答案并给出一个与上面的示例代码相关的代码示例吗?
  • 对不起,我对猫鼬没有经验。上面的语法是 mongo 语法,所以我想任何语言的驱动程序都支持这个。我找到了一些例子,请在我的答案中查看。
【解决方案2】:

这可能是一个像使用一样的附带问题

function (user)

而不是

function(err, user)

对于查找的回调?只是想帮助解决这个问题,因为我已经有这个案例了。

【讨论】:

    【解决方案3】:

    你会想要这样做:

    User.findOne({}, function(err, user){
      user.key_to_delete = undefined;
      user.save();
    });
    

    【讨论】:

    【解决方案4】:

    在早期版本中,您需要下拉 node-mongodb-native 驱动程序。每个模型都有一个集合对象,其中包含 node-mongodb-native 提供的所有方法。因此,您可以通过以下方式执行相关操作:

    User.collection.update({_id: user._id}, {$unset: {field: 1 }});
    

    从 2.0 版开始,您可以:

    User.update({_id: user._id}, {$unset: {field: 1 }}, callback);
    

    从 2.4 版开始,如果您已经有模型实例,您可以这样做:

    doc.field = undefined;
    doc.save(callback);
    

    【讨论】:

    • 这个问题已经在 Mongoose 2.X 中得到修复,所以你可以把收藏放在外面。
    • 要么使用User.update({ _id: id }, { $unset: { field: 1 }}, callback),或者如果您有文档实例,请将路径设置为未定义然后保存:doc.field = undefined; doc.save()
    • 请注意,如果您尝试删除架构中不再定义的旧属性,您需要执行 doc.set('field', undefined)
    • 删除doc.field.foo怎么样?
    • @evilcelery doc.set('field', undefined) 可能还不够,因为严格模式(默认)不允许设置模式中不再存在的字段。 doc.set('field', undefined, { strict: false }) 工作正常。
    【解决方案5】:

    我使用猫鼬,并且使用上述任何功能都满足了我的要求。该函数编译无错误,但该字段仍将保留。

    user.set('key_to_delete', undefined, {strict: false} );
    

    为我做了诀窍。

    【讨论】:

    • 支持这个有用的答案,太糟糕了@alexander-link 在 2015 年没有让它成为答案 (stackoverflow.com/questions/4486926/…)
    • 感谢您的回答,对我来说,其他解决方案不适用于嵌套在数组中的对象!
    • @BenSower 这也是我的情况。只有这个解决方案效果很好,因为我必须在找到特定文档的 id 后删除带有数组的字段
    • 请注意,字符串是键的路径。因此,如果您要删除的对象是嵌套的,您必须找到它的路径。这个答案解决了我的问题!
    【解决方案6】:

    你可以使用 删除用户._doc.key

    【讨论】:

      【解决方案7】:

      Mongoose 文档不是一个普通的 javascript 对象,这就是为什么你不能使用 delete 运算符。(或来自 'lodash' 库的unset)。

      您的选择是设置 doc.path = null ||未定义或使用 Document.toObject() 方法将猫鼬文档转换为普通对象,然后像往常一样使用它。 在 mongoose api-ref 中阅读更多内容: http://mongoosejs.com/docs/api.html#document_Document-toObject

      示例如下所示:

      User.findById(id, function(err, user) {
          if (err) return next(err);
          let userObject = user.toObject();
          // userObject is plain object
      });
      

      【讨论】:

        【解决方案8】:

        所有这些答案的问题在于它们适用于一个领域。例如,假设我想从我的文档中删除所有字段,如果它们是空字符串""。 首先你应该检查字段是否为空字符串把它放到$unset

        function unsetEmptyFields(updateData) {
          const $unset = {};
          Object.keys(updatedData).forEach((key) => {
            if (!updatedData[key]) {
              $unset[key] = 1;
              delete updatedData[key];
            }
          });
          updatedData.$unset = $unset;
        
          if (isEmpty(updatedData.$unset)) { delete updatedData.$unset; }
        
          return updatedData;
        }
        
        function updateUserModel(data){
        const updatedData = UnsetEmptyFiled(data);
        
            const Id = "";
            User.findOneAndUpdate(
              { _id: Id },
              updatedData, { new: true },
            );
        }
        
        

        【讨论】:

          【解决方案9】:

          如果您想从集合中删除密钥,请尝试此方法。

           db.getCollection('myDatabaseTestCollectionName').update({"FieldToDelete": {$exists: true}}, {$unset:{"FieldToDelete":1}}, false, true);
          

          【讨论】:

          • 我不认为问题是关于从集合中的所有文档中删除该字段,这就是这样做的
          【解决方案10】:

          试试:

          User.findOne({}, function(err, user){
            // user.key_to_delete = null; X
            `user.key_to_delete = undefined;`
          
            delete user.key_to_delete;
          
            user.save();
          });
          

          【讨论】:

            【解决方案11】:

            我相信,如果您希望将特定字段删除到集合中,您应该这样做:

            User.remove ({ key_to_delete: req.params.user.key_to_delete});
            

            【讨论】:

            • 不,不要那样做——这将从数据库中删除与该查询匹配的每个文档。根本不是 OP 想要的
            猜你喜欢
            • 2013-09-04
            • 2017-09-28
            • 1970-01-01
            • 2015-04-04
            • 2019-01-04
            • 1970-01-01
            • 2014-05-01
            相关资源
            最近更新 更多