使用 Mongoose 从 MongoDB 文档中删除一个键

Posted

技术标签:

【中文标题】使用 Mongoose 从 MongoDB 文档中删除一个键【英文标题】:Delete a key from a MongoDB document using Mongoose 【发布时间】: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();
);

【问题讨论】:

我以为我找到了它,但经过一些测试:可能没有。不过,这对这个话题有一些很好的讨论。 groups.google.com/group/mongoose-orm/browse_thread/thread/… 哈哈没关系,我猜这是你的帖子! 【参考方案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();
);

【讨论】:

这只会将其设置为 null - 而不是 OP 所要求的。 从 2.4.0 版开始,将文档键设置为 undefined 会将 $unset 传递给 mongodb aaronheckmann.posterous.com/mongoose-240【参考方案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 年没有让它成为答案 (***.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 想要的

以上是关于使用 Mongoose 从 MongoDB 文档中删除一个键的主要内容,如果未能解决你的问题,请参考以下文章

从 MongoDB 和 Mongoose 中的多个文档创建单个文档

根据另一个字段值 mongodb mongoose 从文档中排除字段

使用 Mongoose 在 MongoDB 中更新许多记录的正确方法是啥

mongoose:使用$ pull删除嵌入式文档数组中的值(MongoDB 3.4版本)

通过 Mongoose、Node.js、MongodB 中的特定属性查找嵌入式文档

我无法使用 Mongoose 在 MongoDB 中保存或查找文档