【问题标题】:Why does "$pull" does'nt work with findbyidandupdate request?为什么“$pull”不适用于 findbyidandupdate 请求?
【发布时间】:2020-04-11 03:02:55
【问题描述】:

注意:我有这个警告:DeprecationWarning: Mongoose: findOneAndUpdate()findOneAndDelete() 没有 useFindAndModify 选项设置为 false 已弃用。 我不知道这个警告是什么意思

router.put('/deleteTodoFromUser/:id/:idTodo', passport.authenticate('bearer'), (req, res) => {

  User.findByIdAndUpdate(req.params.id, { $pull: { todos: req.params.idTodo } }, (err, usr) => {
    if (err) {
      res.send(err);
    }
    res.send(usr);
  });
})

【问题讨论】:

  • 你能发布一些示例数据吗?
  • 它只是文档中的一个字符串数组(待办事项)
  • 你想删除user中的引用todo id还是同时删除user中的引用和todos集合中的todo?
  • 只是我想删除用户中的引用
  • 然后@JBone 答案必须按预期工作,它只是返回旧文档,但实际上删除了引用的待办事项。您可以通过添加像 {new: true} 这样的第三个选项来获取更新的文档。这必须在像这样的拉取选项之后{ $pull: { todos: { $eq: req.params.idTodo } } }, {new: true}

标签: node.js mongodb express mongoose


【解决方案1】:

我觉得语法应该是这样的:

  User.findByIdAndUpdate(
    req.params.id,
    { $pull: { todos: { $in: [req.params.idTodo] } } },
    { new: true },
    (err, usr) => {
      if (err) {
        res.send(err);
      }
      res.send(usr);
    }
  );

查看官方文档中的this 链接。

【讨论】:

  • 这个方法findByIdAndUpdate是否存在于您使用的mongo版本中?根据文档,似乎它不在最新版本中
  • 它存在,但在我的情况下只返回相同的对象而不更新。
  • 可能你要考虑findOneAndUpdate
  • console.log(the value is ${req.params.idTodo}) ..看看它打印了什么
  • @JBone 你的答案确实有效,但没有{new:true} 选项,它会返回旧文档,所以我猜这让哈森感到困惑,所以我更新了你的答案。
【解决方案2】:

JBones 的回答必须按预期工作。

但是为了解决你的问题,这里我一步一步解释。

用户架构:

const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
  name: String,
  todos: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Todo"
    }
  ]
});

module.exports = mongoose.model("User", userSchema);

Todo 架构:

const mongoose = require("mongoose");

const todoSchema = new mongoose.Schema({
  name: String,
  completed: Boolean
});

module.exports = mongoose.model("Todo", todoSchema);

路线:

router.put("/deleteTodoFromUser/:id/:idTodo", (req, res) => {
  User.findByIdAndUpdate(
    req.params.id,
    { $pull: { todos: { $in: [req.params.idTodo] } } },
    { new: true },
    (err, usr) => {
      if (err) {
        res.status(500).send(err);
      }
      if (usr) {
        res.send(usr);
      } else {
        res.status(400).send("Bad request - User not found");
      }
    }
  );
});

测试:

假设您的待办事项集合中有这 3 个待办事项文档。

[
    {
        "_id" : ObjectId("5dfa6776e1783d0c10a8d827"),
        "name" : "Todo 3",
        "completed" : true,
        "__v" : NumberInt(0)
    },
    {
        "_id" : ObjectId("5dfa676fe1783d0c10a8d826"),
        "name" : "Todo 2",
        "completed" : false,
        "__v" : NumberInt(0)
    },
    {
        "_id" : ObjectId("5dfa6768e1783d0c10a8d825"),
        "name" : "Todo 1",
        "completed" : false,
        "__v" : NumberInt(0)
    }
]

还有这样的用户文档:

{
    "_id" : ObjectId("5dfa846379db991c3c4341e4"),
    "todos" : [
        ObjectId("5dfa6768e1783d0c10a8d825"),
        ObjectId("5dfa676fe1783d0c10a8d826"),
        ObjectId("5dfa6776e1783d0c10a8d827")
    ],
    "name" : "User 1",
    "__v" : NumberInt(0)
}

当我们尝试删除用户 id 5dfa846379db991c3c4341e4 的待办事项 id 5dfa676fe1783d0c10a8d826 时, url 必须是这样的 http://...../deleteTodoFromUser/5dfa846379db991c3c4341e4/5dfa676fe1783d0c10a8d826

结果会是这样的:(5dfa676fe1783d0c10a8d826 被移除)

{
    "todos": [
        "5dfa6768e1783d0c10a8d825",
        "5dfa6776e1783d0c10a8d827"
    ],
    "_id": "5dfa846379db991c3c4341e4",
    "name": "User 1",
    "__v": 0
}

事实上,如果您检查用户集合,您会在用户文档中看到 2 个待办事项。

【讨论】:

  • 同理,可能问题出在我的猫鼬版本上。导致此请求发生同样的情况: User.findByIdAndUpdate(req.params.id, { $set: { $addToSet: { todos: req.params.idTodo } } }, (err, usr) => {
  • @HassenBouzlima 使用这些模式和代码,它应该可以工作。您可以为您的问题添加一些用户文档和待办事项吗?我认为问题在于如何保存数据。
  • 当我想添加 todo 的引用 Id 以及当我想删除它时,问题只是为了更新而发生
  • @HassenBouzlima 您可以通过编辑您的问题来显示示例文档吗?如果您展示如何保存文档也可能会有所帮助。
  • 现在检查一下,我添加了一个发生在我身上的警告
【解决方案3】:

我想我找到了问题:

  • 首先我在 mongodb 中手动将 Id 添加到数组中,所以我认为它会出现问题
  • 我的 add to set 请求无法正常工作:User.findByIdAndUpdate(req.params.id, { $set{$addToSet: { todos: req.params.idTodo } }} -- > $set 在这里是错误的,只是我在没有 $set 的情况下实现了这个请求并且它起作用了。

所以在那之后,我可以通过 mongoose request 而不是手动将 Id 添加到 todo 数组中。 *正如我所说,我也收到了警告:* 弃用警告:Mongoose:不推荐使用未将 useFindAndModify 选项设置为 false 的 findOneAndUpdate() 和 findOneAndDelete()

为此我添加了: mongoose.connect('mongodb://localhost:27017/Db_Todo',{useUnifiedTopology:true,useNewUrlParser:true,useFindAndModify:false});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 2016-06-02
    • 2015-01-22
    • 2016-12-16
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多