【问题标题】:findByIdAndUpdate pull from array objects equal to a specific valuefindByIdAndUpdate 从等于特定值的数组对象中提取
【发布时间】:2021-05-15 05:52:02
【问题描述】:

我想从用户模型的timeline 列表中删除一个或多个tweet 类型的对象。我要删除的 tweet 对象是其作者 ID 与特定 ID user._id 匹配的对象。

我试过这个:

router.get("/follow/:userId", isLoggedIn, catchAsync(async (req, res) => {
    try {
        const currentUser = await User.findById(req.user._id).populate("timeline")
        const user = await User.findById(req.params.userId).populate("followers tweets")
        for (let tweet of currentUser.timeline) {
            if (tweet.author._id.equals(user._id)) {
                currentUser.timeline.pull(tweet._id)
            }
        }
        req.flash("error", `Unfollowed to ${user.username}`)
        user.save();
        currentUser.save()
        res.redirect(`/${user._id}`)
    } catch (err) {
        req.flash("error", err.message);
        res.redirect("back")
    }
}));

还有这个:

await User.findbyIdAndUpdate(currentuser._id, { $pull: { timeline: { author : user._id } } }

但它们都不起作用。

我的用户模型:

const userSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    biography: { type: String, maxlength: 160 },
    location: {type: String, maxlength: 30 },
    email: {
        type: String,
        unique: true,
        required: true
    },
    image: {
        url: String,
        filename: String,
    },
    followers: [{ type: Schema.Types.ObjectId, ref: "User" }],
    following: [{ type: Schema.Types.ObjectId, ref: "User" }],
    tweets: [{ type: Schema.Types.ObjectId, ref: "Tweet"}],
    timeline: [{ type: Schema.Types.ObjectId, ref: "Tweet"}]
});

我的推文模型:

const tweetSchema = new Schema({
    images: [{ 
        url: String,
        filename : String
    }],
    text: { type: String, maxlength: 260},
    date: { type: Date, default: Date.now },
    author: { type: Schema.Types.ObjectId, ref: "User" },
    parent: { type: Schema.Types.ObjectId, ref: "Tweet", default:null },
    replies: [{ type: Schema.Types.ObjectId, ref: "Tweet" }],
    likes: [{ type: Schema.Types.ObjectId, ref: "User" }],
    retweets: [{ type: Schema.Types.ObjectId, ref: "Tweet" }],
    retweetStatus: {type: Schema.Types.ObjectId, ref: "Tweet", default: null}
});

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    如果你的收藏是这样的:

    [
      {
        "_id" : ObjectId("60254276259a60228cbe5707"),
        "name" : "Mary",
        "timeline" : [
          ObjectId("60254276259a60228cbe5703"),
          ObjectId("60254276259a60228cbe5704"),
          ObjectId("60254276259a60228cbe5705")
        ]
      },
      {
        "_id" : ObjectId("60254276259a60228cbe5706"),
        "name" : "Dheemanth",
        "timeline" : [
          ObjectId("60254276259a60228cbe5700"),
          ObjectId("60254276259a60228cbe5701"),
          ObjectId("60254276259a60228cbe5702")
        ]
      }
    ]
    

    那么解决方法是:

    usersSchema.updateOne(
        {
            "_id": ObjectId("60254276259a60228cbe5706"),
            "timeline": ObjectId("60254276259a60228cbe5700"),
        },
        {
            $pull: {
                "timeline": ObjectId("60254276259a60228cbe5700")
            }
        }
    )
    .then()
    .catch()
    
    // or
    
    usersSchema.findOneAndUpdate(
        {
            "_id": ObjectId("60254276259a60228cbe5706"),
            "timeline": ObjectId("60254276259a60228cbe5700"),
        },
        {
            $pull: {
                "timeline": ObjectId("60254276259a60228cbe5700")
            }
        },
        {
            new: true
        }
    )
    .then()
    .catch()
    

    【讨论】:

    • 感谢您的回复。我在 mongo 中都尝试过,但它不起作用。但我需要让它在我的路线中使用 nodejs,而不是在 mongo 中。谢谢
    • 如果我的答案中的集合架构与您的正确匹配,那么这些查询是正确的。它至少对我有用。
    • 根据您问题中的拼写错误,我只有一个建议。请检查您的代码中查询中使用的字段名称是否有拼写错误。
    • 但是在我的用户 Schema 集合中,时间线是一个对象数组,ID:"timeline" : [ ObjectId("6026883fac4a220fcf85309c"), ObjectId("6026883fac4a220fcf85309c"),] 这就是它在 Mongo 中的显示方式。在我的路线中,我填充了时间线以使用它。
    • 如果您使用 findOneAndUpdate,那么传递具有“true”值的“new”选项很重要。检查更新的答案。
    【解决方案2】:

    我终于找到问题了!我遇到的问题是我试图在循环遍历该列表时从对象列表中删除项目。解决方案很简单:您只需创建一个辅助空数组并推送要删除的项目,然后循环该辅助数组并从原始数组中拉出项目。

    就我而言,我已经有一个数组,其中包含我想要删除的推文,user.tweets。解决办法是:

    router.get("/follow/:userId", isLoggedIn, catchAsync(async (req, res) => {
        try {
            const currentUser = await User.findById(req.user._id).populate("timeline")
            const user = await User.findById(req.params.userId).populate("followers tweets")
            for (let tweet of user.tweets) {
                currentUser.timeline.pull(tweet._id)
            }
            req.flash("error", `Unfollowed to ${user.username}`)
            user.save();
            currentUser.save()
            res.redirect(`/${user._id}`)
        } catch (err) {
            req.flash("error", err.message);
            res.redirect("back")
        }
    }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 2018-11-05
      • 2020-06-04
      • 1970-01-01
      • 2018-08-13
      • 2019-10-08
      • 2015-07-13
      相关资源
      最近更新 更多