为什么mongoose没有常规的数组方法

nnvyjq4y  于 2023-10-19  发布在  Go
关注(0)|答案(1)|浏览(129)

我是mongoose的新手,在我的模式中有一个数组,它是一个嵌套的文档,如下所示:

const userSchema = new Schema({
    username: String
    friends: [friendsSchema],
});

const friendsSchema = new Schema({
    name: { type: String, unique: true },
});

假设我想添加一个朋友到一个特定的用户,我需要做以下事情:

  • 检查用户id是否有效
  • 检查用户id是否存在于数据库中
  • 如果用户存在,检查他是否已经有一个朋友使用该名称
  • 如果他不把一个新朋友推到朋友的行列中,

我最初认为,一旦我获得了用户,我可以简单地在user.friends数组上执行foreach循环来验证朋友的存在。然而,事实证明mongoose数组的行为与常规JavaScript数组不同。这非常令人沮丧,因为这意味着我需要构造一个复杂的查询,可能导致额外的数据库读取,而不是直接访问用户并从用户对象中检查所需的信息。因此,我提出了以下实现:

let { name, userId } = req.body;
    try {
        //check if userId is a valid mongoose objectId
        if (!mongoose.Types.ObjectId.isValid(userId)) {
            res.status(404).json({ error: "invalid user id" });
        }
        // get the user
        let user = await userModel.findById(userId);
        if (!user) {
            res.status(404).json({ error: "user not found" });
        }
        
        let user = user.friends.foreach(friend =>{ 
                   if (friend.name === name)
                      {     
                        res.status(404).json({error: "friend already added to user"});
                      }
        }); 
        
        user.friends.push({ name});
        user.save();
        res.status(200).json(user);
  • 有没有可能在一个查询中完成所有前面的步骤,就像一个数据库读取器完成所有事情一样?
  • 为什么 Mongoose 会有一个独特的阵列类型?

PS:这不是一个重复的问题,如何推和保存到一个数组

pcww981p

pcww981p1#

你不必找到用户并循环通过他们的朋友。你可以只做一个条件更新,如果条件不满足,就把朋友推到数组中。举例来说:
从这里开始删除,然后删除所有内容:

let user = await userModel.findById(userId);

更改为:

const user = await userModel.findOneAndUpdate(
   {
      _id: userId, //< Find a user with this id
      'friends.name': { $ne: name } //< But also can't have a friend already with this name 
   },
   {
      $push: { // If you find a user with that id and no existing friend then push
         "friends": {name: name}
      }
   },
   { new: true } //< This tells mongoose to give you back the user with the friend added i.e the updated version
);
if (!user) {
   res.status(404).json({ error: "user not found or friend already added" });
} else{
   res.status(200).json(user);
}

如果你真的想这样做,你仍然可以首先检查用户是否存在,快速:

const existingUser = await userModel.findById(userId);

然后根据返回值进行有条件更新,但您的应用程序真的不应该允许您的用户尝试更新不存在的用户。

相关问题