【问题标题】:find nested (embedded) object in the collection在集合中查找嵌套(嵌入)对象
【发布时间】:2020-05-21 18:18:57
【问题描述】:

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

Mongoose Find One on Nested Object

How can I find nested objects in a document?

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

    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]});
    }

  }
})

      }
    }
  });
});

这是我的架构,供参考

 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);

示例

{ 
    "_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)
}

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

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

但是 console.log(checkedobj.cmets) 只给出一个对象。

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

【问题讨论】:

  • 您期望的结果形式是什么?
  • 我希望传递我找到后得到的所有对象,并通过 SIMG 传递给 ejs。基本上checkedobj.cmets 应该记录有关所选对象的信息。
  • 你能把console.log的输出(checkedBox);在你的问题?
  • 再次编辑了问题。希望对您有所帮助。

标签: node.js mongodb mongoose


【解决方案1】:

当你想要一个数组中的多个匹配元素时,你应该使用$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) {
    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]});
    }

  }
})

      }
    }
  });
});

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

上面的例子将只返回 2 个匹配 id 的 cmets

【讨论】:

  • 感谢您的回答,但现在 console.log(checkedobj.cmets) 日志未定义。
  • 首先,您是否检查了 mongoplayground 网址,并且您想要这样的输出,所有 cmets 仅匹配来自 cmets 数组?
  • console.log(checkedobj[0].cmets) 这应该可以,请检查更新答案
  • 是的,现在它工作得很好,我现在应该开始称你为超人了。谢谢你的支持。 :)
【解决方案2】:

您可以使用findById() 方法,提供更多关于它的文档here

你可以使用这样的东西来按对象 id 搜索:-

var id = "123";
userSchema.findById(id, function (err, user) { ... } );

希望这会有所帮助!

【讨论】:

  • 可以把userSchema例子的json也发一下吗?
  • 我只能返回一个对象..并非所有对象都被选中并通过复选框
猜你喜欢
  • 2014-05-18
  • 2019-12-31
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多