如何使用_id(node.js)检索mongoDB中关联的子文档

Posted

技术标签:

【中文标题】如何使用_id(node.js)检索mongoDB中关联的子文档【英文标题】:how to retrieve sub documents associated in mongoDB using _id (node.js) 【发布时间】:2020-09-01 02:40:22 【问题描述】:

我试图检索与 id 关联的数据,并将其存储在变量中。 我的数据库看起来像

 
"_id" : ObjectId("5ebc4242c2098c7968853b44"),  //userId
"firstname" : "john", 
"lastname" : "Jacob", 
"username" : "john@abc.com", 
"comments" : [
    
        "_id" : ObjectId("5ebd124e7f92505c9c23b680"),  
        "comment" : "hey there", 
        "imagename" : "image-1589449294815.PNG"
    , 
    
        "_id" : ObjectId("5ebd24b9cae2ab15683460ed"), 
        "comment" : "whazup", 
        "imagename" : "image-1589454009062.jpeg"
    

我正在检索特定的 id(通过复选框选择的图像),并且想要访问特定的评论和关联的图像名称(通过 id),然后通过将图像发送到我的 .ejs 文件SIMG

app.js 看起来像

app.post("/checkout", uploads, function (req, res) 
  User.findById(req.user.id, function (err, foundUser) 
    if (err) 
      console.log(err);
     else 
      if (foundUser) 
const uid = foundUser.id; //this is users id.
var checkedItemId = req.body.checkbox; // this is checked image id.

    User.findById(checkedItemId, function (err, foundID) 
      if (foundID) 
        console.log(foundID);
        console.log(foundID.comment);
        console.log(foundID.imagename);

        res.render("checkout", 
          SIMG: imagename,
        );
      
    );
    if (Array.isArray(req.body.checkbox)) 
          res.render("checkout", 
            SIMG: req.body.checkbox,
          );
         else 
          res.render("checkout", 
            SIMG: [req.body.checkbox],
          );
        
      
    
  );
);

我使用了上面的 findById 方法,但它似乎不起作用,或者我可能没有使用正确的方法。

架构看起来像

const commentSchema = new mongoose.Schema(
  comment: String,
  imagename: String,
);

const Comment = new mongoose.model("Comment", commentSchema);

const userSchema = new mongoose.Schema(
  firstname: String,
  lastname: String,
  email: String,
  password: String,
  comments: [commentSchema],
);



const User = new mongoose.model("User", userSchema);

【问题讨论】:

贴出Schema的代码 hii,我已经编辑了上面的代码以添加架构。谢谢 所以你需要得到只匹配checkedItemId的评论,这个checkedItemId应该代表comment._id还是什么? 什么是_id类型? 是的,我需要同时获取与checkedItemId相关的评论和图片名称。当我登录checkedItemId时,我得到了id值(例如上面senerio中的“5ebd124e7f92505c9c23b680”,我可以通过checkedItemid登录,但我想要评论,即“嘿那里”及其相关的图像名称,即“image-1589449294815.PNG” " ) @mohammedyousry 【参考方案1】:

findById 方法用于通过他们的_id 获取文档,因此当您将checkedItemId 传递给User.findById(checkedItemId) 时它不会返回任何内容,因为这个checkedItemId 不是userId,它是commentId

您可以通过在第一个User.findById(req.user.id) 之后执行一些代码来获得具有此checkedItemIdcomment

类似的东西

app.post("/checkout", uploads, function (req, res) 
    User.findById(req.user.id, function (err, foundUser) 
        if (err) 
            console.log(err);
         else 
            if (foundUser) 
                const uid = foundUser.id; //this is users id.
                var checkedItemId = req.body.checkbox; // this is checked image id.

                // this will return only the comments that have the same id as checkedItemId, 
                // it should be one 

                foundUser.comments = foundUser.comments.filter((comment) =>  comment._id.toString() === checkedItemId.toString() );
                // now you have comments array inside the user object, but this comments array is filtered 

                // If you need to get the image name of that comment, we know that this array has only one element as the id is unique,
                // so we can use comments[0] to get the imagename
                var imagename = foundUser.comments[0].imagename;

                // do the res.render here

                if (Array.isArray(req.body.checkbox)) 
                    res.render("checkout", 
                        SIMG: req.body.checkbox,
                    );
                 else 
                    res.render("checkout", 
                        SIMG: [req.body.checkbox],
                    );
                
            
        
    );
);

还有另一种方法可以直接从查询中获取与checkedItemId 匹配的评论,使用带有$filter 的聚合管道

app.post("/checkout", uploads, function (req, res) 
    User.aggregate([
        
            $match:  _id: mongoose.Types.ObjectId(req.user.id) 
        ,
        
            $project: 
                firstname: 1,
                lastname: 1,
                username: 1,
                comments: 
                    $filter: 
                        input: '$comments',
                        as: 'comment',
                        cond: 
                            $eq: ['$$comment._id', mongoose.Types.ObjectId(checkedItemId)]
                        
                    
                
            
        
    ]).exec().then(function (users)  // the aggregate is returning an array

        console.log(users); // this users should have only one document as the user id is unique I guess
        // this document has a comments array with only one comment as the comment id is unique too

        // here you can do the render

    );
);

希望对你有帮助

【讨论】:

非常感谢。通过将 checkedItemId 更改为 req.body.checkbox,我能够使用聚合管道方法获取对象。

以上是关于如何使用_id(node.js)检索mongoDB中关联的子文档的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mongoose 在投影中包含 Mongodb“_id”字段

node.js mongodb 通过_id node-mongodb-native 选择文档

如何将 mongodb 数据从服务器(node.js)检索到我的 AngularJS 路由

如何将 MongoDB 查询从 Node.js 驱动程序格式调整为 Mongoose 格式

MongoDB:如何使用 _id 获取集合中的最新文档?

02_使用Node.js往mongodb插入数据