简体   繁体   English

在 mongodb 中的嵌套文档中查询

[英]Query in nested document in mongodb

Here is my mongoose schema:这是我的猫鼬模式:

const chapterSchema = mongoose.Schema({
title: {
    type: String
},
number: {
    type: Number
}
})

const bookSchema = mongoose.Schema({
    title: {
        type: String
    },
    author: {
        type: String
    },
    chapters: [chapterSchema]
})

const Book = mongoose.model('Book', bookSchema)
module.exports = Book

Here is my database:这是我的数据库:

{
"_id": "5f56f8e66a7eee227c1acc0a",
"title": "Book1",
"author": "Author1",
"chapters": [{
    "_id": "5f56fa47a78fbf03cc32d16d",
    "title": "Chapter1",
    "number": 1
}, {
    "_id": "5f56fad10820300de031317f",
    "title": "Chapter2",
    "number": 2,
}]
}

I want to find a specific chapter from the chapters array by it's id.我想通过它的 id 从章节数组中找到一个特定的章节 So, I wrote this code:所以,我写了这段代码:

router.get('/:id', async function (req, res) {
try {
    const id = req.params.id
    await Book.findById(id, function (err, chapter) {
        res.render('chapter.hbs', {
            chapter: chapter
        })
    })
} catch (error) {
    res.redirect('/')
}
})

According to the chapter id, I want this result:根据章节id,我想要这个结果:

{
    "_id": "5f56fa47a78fbf03cc32d16d",
    "title": "Chapter1",
    "number": 1
}

or或者

{
    "_id": "5f56fad10820300de031317f",
    "title": "Chapter2",
    "number": 2,
}

What should I do to find a specific chapter using it's id?我应该怎么做才能使用它的 id 查找特定章节?

You are searching on Book using findById of chapters Id, it will not give result since it is not Book Id,您正在使用章节 Id 的 findById 搜索 Book,它不会给出结果,因为它不是 Book Id,

You will need to use $elemMatch for this您需要为此使用$elemMatch

check this Querying for Object in Mongoose Sub Array for reference检查此查询 Mongoose 子数组中的对象以供参考

You can do this using the aggregate function.您可以使用聚合函数执行此操作。

router.get('/:id', async function (req, res) {
  try {
    const id = req.params.id
    await Books.aggregate([
      {
        $project: {
          title: 1,
          author: 1,
          chapters: {
            $filter: {
              input: "$chapters",
              as: "chapter",
              cond: {
                $eq: [
                  "$$chapter.id", id
                ]
              }
            }
          }
        }
      }
    ])
  } catch (error) {
    res.redirect('/')
  }
})

You can use aggregate() function,您可以使用aggregate()函数,

  • $match your condition $match你的条件
  • $filter to get specific chapter id $filter获取特定章节 ID
  • $replaceWith to replace chapter in root $replaceWith替换 root 中的章节
const id = mongoose.Types.ObjectId(req.params.id);

let chapter = await Book.aggregate([
  { $match: { "chapters._id": id } },
  {
    $replaceWith: {
      $arrayElemAt: [
        {
          $filter: {
            input: "$chapters",
            cond: { $eq: ["$$this._id", id] }
          }
        },
        0
      ]
    }
  }
]);

console.log(chapter);

Playground操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM