【问题标题】:How do I query a referenced object in MongoDB如何在 MongoDB 中查询引用的对象
【发布时间】:2021-02-16 01:06:59
【问题描述】:

我的 mongo 数据库中有两个集合:Book 和 Author

图书收藏有一个作者字段,它引用创建它的作者

const schema = new mongoose.Schema({
  ...
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Author'  
})

我正在使用 graphql,我当前的代码如下所示。 booksByAuthor 是一个查询,它接受一个名字,然后返回该作者所写的书籍。(这是有效的,并且给了我正确的输出)

booksByAuthor: async (root) => {
  const author = await Author.findOne({name: root.name})
  
  return await Book.find({
    author: author._id
  })
}

我目前的实现是先查询Author集合,然后使用作者的id再查询Book集合。但是,我觉得必须有一种方法可以在不通过 Author 集合的情况下执行此操作。

理想情况下,我希望它是这样的:(伪代码)

return await Book.find({
   author.name: {root.name}

})

我试过了

  return await Book.find({
    "author.name": { $in: [root.name] }
  })

  return await Book.find({
    name: { author: { $in: [root.name] } }
  })

但两者都返回一个空数组。我不知道我是否应该在这种情况下使用 $in

【问题讨论】:

  • 请添加一些来自作者和书籍收藏的示例文档,以便我们编写查询。
  • 为什么你认为你可以绕过Author?如果Author 有一个键和名称,例如_id: ObjectId1, name: Buzz 并且查询是按名称进行的,那么您必须反向映射到 _id 以执行对 Books 集合的查找。

标签: reactjs mongodb graphql


【解决方案1】:

您可以使用$lookup 在单个查询中实现此目的。 $lookup 类似于 sql 中的joins

根据您的问题,我创建了一些示例文档。以下是按作者获取书籍的查询。

db.book.aggregate([
  {
    "$lookup": {
      "from": "author",
      "localField": "author",
      "foreignField": "_id",
      "as": "author"
    }
  },
  {
    "$match": {
      "author.name": "Kafka"
    }
  }
])

这里是Mongo Playground。请点击链接查看实际查询。您还可以看到我使用的示例文档。根据您的需要随意使用它。

【讨论】:

    猜你喜欢
    • 2012-03-26
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2018-02-06
    相关资源
    最近更新 更多