[英]What is the correct type to use for an ObjectId field across mongoose and GraphQL?
Following this tutorial , I have a mongoose model: (I'm using the term "Account" instead of "Todo", but it's the same thing) 在本教程之后 ,我有一个猫鼬模型:(我使用术语“帐户”而不是“Todo”,但它是一样的)
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
and a GraphQLObjectType: 和GraphQLObjectType:
const AccountType = new GraphQLObjectType({
name: 'account',
fields: function () {
return {
id: {
type: GraphQLID
},
name: {
type: GraphQLString
}
}
}
});
and a GraphQL mutation to create one of these: 和GraphQL突变创建其中之一:
const mutationCreateType = new GraphQLObjectType({
name: 'Mutation',
fields: {
add: {
type: AccountType,
description: 'Create new account',
args: {
name: {
name: 'Account Name',
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: (root, args) => {
const newAccount = new Account({
name: args.name
});
newAccount.id = newAccount._id;
return new Promise((resolve, reject) => {
newAccount.save(err => {
if (err) reject(err);
else resolve(newAccount);
});
});
}
}
}
})
After running the query: 运行查询后:
mutation {
add(name: "Potato")
{
id,
name
}
}
in GraphiQL, I get the response: 在GraphiQL中,我得到了响应:
{
"errors": [
{
"message": "ID cannot represent value: { _bsontype: \"ObjectID\", id: <Buffer 5b 94 eb ca e7 4f 2d 06 43 a6 92 20> }",
"locations": [
{
"line": 33,
"column": 5
}
],
"path": [
"add",
"id"
]
}
],
"data": {
"add": {
"id": null,
"name": "Potato"
}
}
}
The creation of the object was successful, and I can see it in MongoDB Compass: 对象的创建是成功的,我可以在MongoDB Compass中看到它:
but there seems to be a problem reading the value. 但阅读价值似乎有问题。
How compatible are GraphQLID
and mongoose.Schema.Types.ObjectId
? 如何兼容是
GraphQLID
和mongoose.Schema.Types.ObjectId
? If they are not compatible, am I misunderstanding the tutorial, particularly it's use of: 如果它们不兼容,我是否误解了教程,特别是它的使用:
newAccount.id = newAccount._id;
? ? I can't tell if the error is being thrown by GraphQL, or MongoDB, or Mongoose, or something else entirely.
我无法判断GraphQL,MongoDB或Mongoose或其他东西是否抛出了错误。
EDIT 编辑
Any information on the error 有关错误的任何信息
ID cannot represent value: { _bsontype: \\"ObjectID\\", id: }
ID不能代表值:{_bsontype:\\“ObjectID \\”,id:}
would be very helpful. 会非常有帮助的。 I feel it's telling me it couldn't serialize a BSON object .. but then it displays it serialized.
我觉得它告诉我它无法序列化一个BSON对象..然后它显示它序列化。 Even knowing what tech (mongo? mongoose? graphql?) was generating the error would help.
即使知道什么技术(mongo?mongoose?graphql?)产生错误也会有所帮助。 I'm not having any luck with Google.
我对谷歌没有任何好运。
EDIT 2 编辑2
This was a caused by a change to the graphql package introduced recently, and there is a PR awaiting merge which resolves it. 这是由最近引入的graphql包的更改引起的,并且有一个等待合并的PR解决了它。
I didn't find an issue and ran this code with one of my existing code bases. 我没有发现问题,并使用我现有的代码库运行此代码。 Except I wrapped the mutation in the
GraphQLObjectType
. 除了我在
GraphQLObjectType
包装了变异。
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addAccount: {
type: AccountType,
description: 'Create new account',
args: {
name: {
name: 'Account Name',
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: (root, args) => {
const newAccount = new Account({
name: args.name
});
newAccount.id = newAccount._id;
return new Promise((resolve, reject) => {
newAccount.save(err => {
if (err) reject(err);
else resolve(newAccount);
});
});
}
}
});
To get the working example: Clone the repo. 获取工作示例: 克隆回购。 In this repo, the app uses
v0.13.2
and you are using v14.0.2
installed via npm i graphql
. 在这个repo中,应用程序使用
v0.13.2
,你使用的v14.0.2
通过npm i graphql
安装的npm i graphql
。 Downgrade graphql
to v0.13.2
. 降级
graphql
到v0.13.2
。
I used ID
and it works fine! 我使用
ID
,它工作正常! cause of your problem is not id's type! 你的问题的原因不是id的类型! it's becuase you provide it with wrong value:
ObjectID('actuall id')
这是因为你提供了错误的值:
ObjectID('actuall id')
In order to fix this issue, call toJson
function for each fetched data, or simply add a virtual id
like this: 为了解决这个问题,请为每个获取的数据调用
toJson
函数,或者只是添加如下的虚拟id
:
YourSchema.virtual('id').get(function() {
return this.toJSON()._id
}
So what I just found is that _id
is of type ObjectID
but seems to implicitly cast to String
. 所以我刚发现
_id
是ObjectID
类型,但似乎隐式地转换为String
。 So if you define your mongoose model id type to be String
instead of mongoose.Schema.Types.ObjectId
then it should work. 因此,如果您将mongoose模型id类型定义为
String
而不是mongoose.Schema.Types.ObjectId
那么它应该可以工作。 Using your current code (from the compose.com tutorial) that copies _id to id, the result will be that, in Mongo (after saving), the _id will be of type ObjectID
and your model id will be of type string. 使用将_id复制到id的当前代码(来自compose.com教程),结果将是Mongo(保存后),_id将是
ObjectID
类型,您的模型ID将是string类型。
In other words, instead of this 换句话说,而不是这个
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
Do this 做这个
const Account = mongoose.model('Account', new mongoose.Schema({
id: String,
name: String
}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.