【问题标题】:Mongoose .populate() not working correctlyMongoose .populate() 无法正常工作
【发布时间】:2021-06-15 10:31:54
【问题描述】:

我正在尝试使用 GraphQL 和 MERN 创建一个 Tumblr 克隆。现在我只是在尝试为带有照片的帖子创建模板。

以防万一,我正在使用 axios 进行定期 REST 发布请求并为图像文件表达。我从这些人那里得到响应,映射到 _ids 并将它们发送到 createPost 突变中。

在 graphiql 中,我可以查询单个 Image 模型并让一切恢复正常,如下所示:

{
  image(_id: "someId"){
    _id
    url
   created
  }
}

但是,当我使用已推送到 Post 数组中的 ObjectIds 进行子查询时,除了 _id 和 __typename 之外的所有内容都为 null:

{
  post(_id: "someId"){
    _id
    mainImages {
     _id   //returns value
     url  //returns null
     created   //returns null
     __typename   //returns value
   }
  }
}

帖子有两个对象数组,其中 ObjectId 和 ref 用于图像,即 Post 模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const PostSchema = new Schema({
  mainImages: [
    {
      type: Schema.Types.ObjectId,
      ref: 'Image'
    }
  ],
  bodyImages: [
    {
      type: Schema.Types.ObjectId,
      ref: 'Image'
    }
  ],
})

module.exports = mongoose.model('Post', PostSchema, 'posts')

图像模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ImageSchema = new Schema({
  url: {
    type: String,
    required: true
  },
  created: {
    type: Date,
    required: true
  }
})

module.exports = Image = mongoose.model('Image', ImageSchema, 'images');

帖子类型:

const PostType = new GraphQLObjectType({
  name: 'PostType',
  fields: () => ({
    _id: { type: GraphQLID },
    mainImages: { 
      type: new GraphQLList(ImageType),
      resolve(parentValue) {
        return Post.findById(parentValue._id)
          .populate('images')
          .then(post => post.mainImages)
      }
    },
    bodyImages: {
      type: new GraphQLList(ImageType),
      resolve(parentValue) {
        return Post.findById(parentValue._id)
          .populate('images')
          .then(post => post.bodyImages)
      }
    },
  })
})

module.exports = PostType;

我想知道.populate('images') 是否工作不正常。我认为如果你有 ObjectIds,那么.populate() 可以处理剩下的事情。我一直在寻找一堆不同的问题,但似乎没有一个与我的情况足够相关,而且 GraphQL 和 Mongoose 文档也没有给我带来突破。

【问题讨论】:

    标签: node.js mongodb mongoose graphql


    【解决方案1】:

    好吧,在最新版本的我没有正确阅读文档时,我终于弄清楚我做错了什么。

    .populate() 接受一个字符串,该字符串表示在文档中您尝试填充的字段的路径

    我在阅读 populating multiple fields in a single document. 时找到了解决方案

    出于某种原因,我认为“路径”应该指向数据库中集合的名称:

    const PostType = new GraphQLObjectType({
      name: 'PostType',
      fields: () => ({
        _id: { type: GraphQLID },
        mainImages: { 
          type: new GraphQLList(ImageType),
          resolve(parentValue) {
            return Post.findById(parentValue._id)
              .populate('images') //incorrectly pointing towards the collection in db
              .then(post => post.mainImages)
          }
        },
        bodyImages: {
          type: new GraphQLList(ImageType),
          resolve(parentValue) {
            return Post.findById(parentValue._id)
              .populate('images') //incorrectly pointing towards the collection in db
              .then(post => post.bodyImages)
          }
        },
      })
    })
    
    module.exports = PostType;
    

    它应该指向文档/模型本身:

    const PostType = new GraphQLObjectType({
      name: 'PostType',
      fields: () => ({
        _id: { type: GraphQLID },
        mainImages: {      //this is the 'path'
          type: new GraphQLList(ImageType),
          resolve(parentValue) {
            return Post.findById(parentValue._id)
              .populate('mainImages') //that's referenced here
              .then(post => post.mainImages)
          }
        },
        bodyImages: { 
          type: new GraphQLList(ImageType),
          resolve(parentValue) {
            return Post.findById(parentValue._id)
              .populate('bodyImages') //and once again
              .then(post => post.bodyImages)
          }
        }
      })
    })
    
    export default PostType;
    

    这解决了我的问题,我的所有 GraphQL 子查询现在都可以正常工作。另一天,另一集我没有正确阅读文档。

    【讨论】: