在集合中查找嵌套(嵌入)对象 [英] find nested (embedded) object in the collection

查看:55
本文介绍了在集合中查找嵌套(嵌入)对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在 StackOverflow 上解决我的问题时,我注意到之前也有人问过同样的问题,但他们都没有得到好的回应或实际的答案.

Mongoose 在嵌套对象上找到一个

如何在文档中查找嵌套对象?

回到我的问题:我想找到嵌套在模式中的对象.尝试 findMany 提供所有对象,而 findOne 只提供第一个对象,但我想要通过 req.body.checkbox 传递其 ID 的特定对象.我的 JS 代码就像..

 app.post("/data", uploads, function (req, res) {User.findById(req.user.id, function (err, foundUser) {如果(错误){控制台日志(错误);} 别的 {如果(发现用户){var checkBox = req.body.checkbox;console.log(checkedBox);User.findMany({_id:foundUser._id},{comments:{$elemMatch:{_id:checkedBox}}} ,function(err,checkedobj){如果(错误){控制台日志(错误);}别的{console.log(checkedobj.comments);如果(Array.isArray(checkedobj.comments)){res.render("checkout",{SIMG: checkedobj.comments});} 别的 {res.render("checkout",{SIMG: [checkedobj.comments]});}}})}}});});

这是我的架构,供参考

 const commentSchema = new mongoose.Schema({评论:字符串,图像名称:字符串,权限:{type:Number,default:0},});const Comment = new mongoose.model("Comment", commentSchema);const userSchema = new mongoose.Schema({名字:字符串,姓氏:字符串,电子邮件:字符串,密码:字符串,评论:[commentSchema],权限:{type:Number,default:0},});userSchema.plugin(passportLocalMongoose);const User = new mongoose.model("User", userSchema);

示例

<代码>{"_id" : ObjectId("5ec3f54adfaa1560c0f97cbf"),名字":q","姓氏" : "q","用户名": "q@q.com",盐" : "***",哈希":***","__v" : NumberInt(2),注释" : [{权限":NumberInt(0),"_id" : ObjectId("5ec511e54db483837885793f"),评论":嗨","imagename" : "image-1589973477170.PNG"}],权限":NumberInt(1)}

<块引用>

此外,当我选中 3 个复选框时,console.log(checkBox) 日志:

<预><代码>['5ec543d351e2db83481e878e','5ec589369d3e9b606446b776','5ec6463c4df40f79e8f1783b']

但是 console.log(checkedobj.comments) 只给出了一个对象.

<预><代码>[{权限:0,_id:5ec543d351e2db83481e878e,评论:'q',图像名称:'图像-1589986259358.jpeg'}]

解决方案

当你想要一个数组中的多个匹配元素时,你应该使用 $filter 聚合运算符

作为预防措施,首先检查 req.body.checkbox 是否为数组并将其转换为 ObjectIds 数组

app.post("/data", uploads, function (req, res) {var ObjectId = mongoose.Types.ObjectId;User.findById(req.user.id, function (err, foundUser) {如果(错误){控制台日志(错误);} 别的 {如果(发现用户){var checkBox = req.body.checkbox;如果 (!Array.isArray(checkedBox)) {选中框 = [选中框]}console.log(checkedBox);var checkedBoxArray = checkedBox.map(id => ObjectId(id))用户.聚合([{$match: {_id: foundUser._id}},{$项目:{注释: {$过滤器:{输入:$comments",如:评论",条件:{$in:[$$comment._id",checkedBoxArray]}}}}}],函数(错误,检查对象){如果(错误){控制台日志(错误);}别的{console.log(checkedobj[0].comments);如果(Array.isArray(checkedobj[0].comments)){res.render("checkout",{SIMG: checkedobj[0].comments});} 别的 {res.render("checkout",{SIMG: [checkedobj[0].comments]});}}})}}});});

工作示例 - https://mongoplayground.net/p/HnfrB6e4E3C

上面的例子将只返回 2 条与 id 匹配的评论

while i was going through my problem on StackOverflow,i noticed same question was asked before aswell,but none of them had got a good response,or an actual answer.

Mongoose Find One on Nested Object

How can I find nested objects in a document?

well back to my question: i wanted to find the object that is nested in the schema. trying findMany gives all the objects,and findOne give just the first one,but i want particular objects whose id i pass through req.body.checkbox. my JS code goes like..

    app.post("/data", uploads, function (req, res) {
User.findById(req.user.id, function (err, foundUser) {
    if (err) {
      console.log(err);
    } else {
      if (foundUser) {

        var checkedBox = req.body.checkbox;
console.log(checkedBox);
User.findMany({_id:foundUser._id},{comments:{$elemMatch:{_id:checkedBox}}} ,function(err,checkedobj){

  if(err){
    console.log(err);
  }
  else{
  console.log(checkedobj.comments);




    if (Array.isArray(checkedobj.comments)) {
      res.render("checkout",{SIMG: checkedobj.comments});
    } else {
      res.render("checkout",{SIMG: [checkedobj.comments]});
    }

  }
})

      }
    }
  });
});

here is my schema,for reference

 const commentSchema = new mongoose.Schema({
  comment: String,
  imagename: String,
    permission:{type:Number,default:0},
});

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

const userSchema = new mongoose.Schema({
  firstname: String,
  lastname: String,
  email: String,
  password: String,
  comments: [commentSchema],
  permission:{type:Number,default:0},
});

userSchema.plugin(passportLocalMongoose);

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

example

{ 
    "_id" : ObjectId("5ec3f54adfaa1560c0f97cbf"), 
    "firstname" : "q", 
    "lastname" : "q", 
    "username" : "q@q.com", 
    "salt" : "***", 
    "hash" : "***", 
    "__v" : NumberInt(2), 
    "comments" : [
        {
            "permission" : NumberInt(0), 
            "_id" : ObjectId("5ec511e54db483837885793f"), 
            "comment" : "hi", 
            "imagename" : "image-1589973477170.PNG"
        }
    ], 
    "permission" : NumberInt(1)
}

also when i check 3 checkboxes, console.log(checkBox) logs:

[
  '5ec543d351e2db83481e878e',
  '5ec589369d3e9b606446b776',
  '5ec6463c4df40f79e8f1783b'
]

but console.log(checkedobj.comments) gives only one object.

[
  {
    permission: 0,
    _id: 5ec543d351e2db83481e878e,
    comment: 'q',
    imagename: 'image-1589986259358.jpeg'
  }
]

解决方案

When you want multiple matching elements from an array you should use $filter aggregation operator

And as a precaution, first check req.body.checkbox is an array or not and convert it into an array of ObjectIds

app.post("/data", uploads, function (req, res) {
var ObjectId = mongoose.Types.ObjectId;
User.findById(req.user.id, function (err, foundUser) {
    if (err) {
      console.log(err);
    } else {
      if (foundUser) {

var checkedBox = req.body.checkbox;
if (!Array.isArray(checkedBox)) {
    checkedBox = [checkedBox]
}
console.log(checkedBox);
var checkedBoxArray = checkedBox.map(id => ObjectId(id))
User.aggregate([
   {$match: {_id: foundUser._id}},
   {
      $project: {
         comments: {
            $filter: {
               input: "$comments",
               as: "comment",
               cond: { $in: [ "$$comment._id", checkedBoxArray ] }
            }
         }
      }
   }
],function(err,checkedobj){

  if(err){
    console.log(err);
  }
  else{
  console.log(checkedobj[0].comments);




    if (Array.isArray(checkedobj[0].comments)) {
      res.render("checkout",{SIMG: checkedobj[0].comments});
    } else {
      res.render("checkout",{SIMG: [checkedobj[0].comments]});
    }

  }
})

      }
    }
  });
});

Working example - https://mongoplayground.net/p/HnfrB6e4E3C

Above example will return only 2 comments matching the ids

这篇关于在集合中查找嵌套(嵌入)对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆