You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraphQL查询报Cannot read properties of null (reading '_doc')错误

运行GraphQL查询遇到的错误

执行查询时返回的报错信息如下:

{
  "errors": [
    {
      "message": "Cannot read properties of null (reading '_doc')",
      "locations": [
        {
          "line": 38,
          "column": 5
        }
      ],
      "path": [
        "songs",
        0,
        "creator"
      ]
    }
  ],
  "data": null
}

使用的查询语句如下:

query {
  songs {
    song_file_name
    song_type
    song_size
    user_name
    creator {
      email
    }
  }
}

定义的Schema代码如下:

const { buildSchema } = require('graphql');

module.exports = buildSchema(`
type Song {
  _id: ID!
  song_file_name: String!
  song_type: String!
  song_size: Int!
  user_name: String!
  creator: User!
}
type User {
  _id: ID!
  email: String!
  password: String
  createdSongs: [Song!]
}
input SongInput {
  song_file_name: String!
  song_type: String!
  song_size: Int!
  user_name: String!
}
input UserInput {
  email: String!
  password: String!
}
type RootQuery {
    songs: [Song!]!
}
type RootMutation {
    createSong(songInput: SongInput): Song
    createUser(userInput: UserInput): User
}
schema {
    query: RootQuery
    mutation: RootMutation
}
`);

从报错路径可定位到songs数组第一条数据的creator字段解析异常,需要明确错误产生原因、修复方案,同时获取GraphQL关联数据设计与实现相关的进阶学习资源。

错误产生原因

报错是两个问题叠加导致的:

  1. 关联数据查询逻辑缺失:使用原生buildSchema构建Schema时,GraphQL不会自动处理跨集合/表的关联查询,默认resolver只会读取父返回对象上的同名字段。当前songs查询的resolver只查询了歌曲本身的数据,没有关联查询creator对应的用户信息,解析creator字段时拿到的是null值,后续尝试读取null对象上Mongoose文档内部的_doc属性时直接抛出异常。
  2. Schema约束与实际数据不匹配:Schema中给Song类型的creator字段加了!非空标记,意味着GraphQL预期该字段永远不会返回null,但实际数据库里要么第一条歌曲关联的创建者id对应用户已被删除、要么创建歌曲时没有正确写入creator关联id,本身就存在creator为null的脏数据,非空校验直接阻断了整个查询返回。
修复方案

按以下步骤调整即可解决问题:

  • 先清理历史脏数据:检查数据库songs集合中第一条记录的creator关联字段,修复空值、无效用户id的问题,保证所有歌曲记录都绑定了存在的用户id。
  • 补全关联字段解析逻辑:如果使用Mongoose作为ODM,在songs查询的链式调用中添加.populate('creator'),在查询歌曲时一并把关联的用户数据查出来;如果不使用populate,就单独为Song类型的creator字段编写resolve方法,拿到当前歌曲对象存储的creator用户id后,去users集合查询对应用户数据返回。
  • 对齐Schema约束和业务逻辑:如果业务上确实允许歌曲不绑定创建者,就把Schema中creator: User!的非空标记去掉,改成creator: User,避免非空校验直接阻断整个查询。
进阶学习建议

关联数据是GraphQL项目落地的核心模块,针对目前的学习阶段,可以按以下路径推进:

  • 先吃透GraphQL的字段解析规则:GraphQL执行查询时是逐字段递归解析的,父字段resolve返回的对象会作为子字段resolver的第一个入参,嵌套关联字段不会自动拉取数据,必须手动编写resolve逻辑或者借助工具优化查询。
  • 重点掌握DataLoader的用法:手写关联查询最容易出现经典的N+1查询问题,DataLoader是GraphQL生态通用的批量查询、缓存工具,几乎所有生产环境的GraphQL服务都会用它优化关联查询性能,官方仓库有非常详细的用法示例。
  • 可以尝试切换到更工程化的GraphQL服务实现,比如Apollo Server,相比原生buildSchema的写法,它的resolver结构更清晰,嵌套字段的resolve逻辑写法更直观,官方文档包含完整的关联数据设计、性能优化最佳实践,跟着官方示例练习一遍就能打通关联实现的底层逻辑。
  • 练习时不要只照搬教程代码,每写一个resolver就加日志打印入参和返回值,明确每一层字段解析时拿到的数据结构,搞懂每一步数据的流转逻辑,比硬记教程步骤效率高很多。

内容的提问来源于stack exchange,提问作者TheNomadicAspie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:51:23