GraphQL Mongoose:转换为 ObjectId 的值失败
Posted
技术标签:
【中文标题】GraphQL Mongoose:转换为 ObjectId 的值失败【英文标题】:GraphQL Mongoose: Cast to ObjectId failed for value 【发布时间】:2021-03-09 12:49:22 【问题描述】:我有以下 GraphQL 解析器:
const Post = require("../../models/Post");
module.exports =
getAllActivePosts: async (userId) =>
try
const posts = await Post.find(
userId: userId
)
.select(["name", "createdAt"])
.populate("posts", ["name", "createdAt"]);
return posts;
catch (err)
console.log(err);
throw err;
,
;
它试图通过 Post 模型中的用户 ID 获取所有活跃的帖子:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const PostSchema = new mongoose.Schema(
userId:
type: Schema.Types.ObjectId,
ref: "User",
required: true,
,
content:
type: String,
required: true,
,
createdAt:
type: Date,
required: true,
);
module.exports = Post = mongoose.model("Post", PostSchema);
这是 GraphQL 架构:
const buildSchema = require('graphql');
module.exports = buildSchema(`
type User
_id: MongoId!
email: String!
password: String
type Post
_id: MongoId!
userId: MongoId!
content: String!
createdAt: String!
scalar MongoId
input LoginInput
email: String!
password: String!
type RootQuery
login(email: String!, password: String!): AuthData!
getAllActivePosts(userId: MongoId!): [Post]
type RootMutation
createUser(loginInput: LoginInput): AuthData!
schema
query: RootQuery
mutation: RootMutation
`);
...以及我在 GraphiQL 中运行的 GraphQL 查询:
getAllActivePosts(userId: "5fbfc92312b90071179a160f")
name
createdAt
为此,查询的结果是:
"errors": [
"message": "Cast to ObjectId failed for value \" userId: '5fbfc92312b90071179a160f' \" at path \"userId\" for model \"Post\"",
"locations": [
"line": 2,
"column": 3
],
"path": [
"getAllActivePosts"
]
],
"data":
"getAllActivePosts": null
在此处搜索类似问题,尝试将 userId
包装在 ObjectId
中,但没有任何帮助。我在这里错过了什么?
【问题讨论】:
【参考方案1】:一年前我曾遇到过一次这个问题,直到我得到了 graphql 的主要概念。 你在这里传递字符串
getAllActivePosts(userId: "5fbfc92312b90071179a160f")
name
createdAt
并且 graphql 期望有 mongoose.Types.ObjectId
getAllActivePosts(userId: MongoId!): [Post]
你需要做同步
getAllActivePosts(userId: mongoose.Types.ObjectId("5fbfc92312b90071179a160f"))
但是使用上述方式,您没有资格在 graphiQL 中运行查询,因为没有定义猫鼬。
type RootQuery
login(email: String!, password: String!): AuthData!
getAllActivePosts(userId: String!): [Post]
更好的解决方案是使用 userId 输入作为字符串,然后在您的解析器函数上进行验证,例如
getAllActivePosts: async ( userId ) =>
try
if(mongoose.Types.ObjectId.isValid(userId))
const posts = await Post.find(
userId: userId
)
.select(["name", "createdAt"])
.populate("posts", ["name", "createdAt"]);
// you can;t return null you need to return array
return posts ? posts : []
else
// if mongoose id is wrong
return []
catch(error)
// it is better to throw error return blank array to complete flow
throw error
【讨论】:
谢谢,我试过了,帖子里提到过。它没有帮助。 您是否在查询getAllActivePosts(userId: String!): [Post]
中执行此操作,因为我有它的工作代码。谢谢
谢谢,我找到了解决方案并在下面回答。谢谢你的字符串!【参考方案2】:
原来,我直接使用userId
,而我应该使用args.userId
。下面的正确解析器:
module.exports =
getAllActivePosts: async (args) =>
try
const posts = await Post.find(
userId: args.userId
)
.select(["name", "createdAt"])
.populate("posts", ["name", "createdAt"]);
return posts;
catch (err)
console.log(err);
throw err;
,
;
对于架构:
getAllActivePosts(userId: String!): [Post]
【讨论】:
async ( userId ) =>
使用解构赋值以上是关于GraphQL Mongoose:转换为 ObjectId 的值失败的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Mongoose 与 GraphQL 和 DataLoader 一起使用?
GraphQL & Mongoose Schema - 如何将一组 mongoose objectId 引用存储到另一种类型?