【问题标题】:how to retrieve sub documents associated in mongoDB using _id (node.js)如何使用_id(node.js)检索mongoDB中关联的子文档
【发布时间】: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

标签: node.js mongodb mongoose ejs


【解决方案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,我能够使用聚合管道方法获取对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 2011-01-15
  • 2021-10-29
  • 2011-06-21
相关资源
最近更新 更多