![](/img/trans.png)
[英]Mongoose schema mixed type field errantly saving ObjectId field as a String
[英]What is the correct type to use for an ObjectId field across mongoose and GraphQL?
在本教程之后 ,我有一个猫鼬模型:(我使用术语“帐户”而不是“Todo”,但它是一样的)
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
和GraphQLObjectType:
const AccountType = new GraphQLObjectType({
name: 'account',
fields: function () {
return {
id: {
type: GraphQLID
},
name: {
type: GraphQLString
}
}
}
});
和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);
});
});
}
}
}
})
运行查询后:
mutation {
add(name: "Potato")
{
id,
name
}
}
在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"
}
}
}
对象的创建是成功的,我可以在MongoDB Compass中看到它:
但阅读价值似乎有问题。
如何兼容是GraphQLID
和mongoose.Schema.Types.ObjectId
? 如果它们不兼容,我是否误解了教程,特别是它的使用:
newAccount.id = newAccount._id;
? 我无法判断GraphQL,MongoDB或Mongoose或其他东西是否抛出了错误。
编辑
有关错误的任何信息
ID不能代表值:{_bsontype:\\“ObjectID \\”,id:}
会非常有帮助的。 我觉得它告诉我它无法序列化一个BSON对象..然后它显示它序列化。 即使知道什么技术(mongo?mongoose?graphql?)产生错误也会有所帮助。 我对谷歌没有任何好运。
编辑2
我没有发现问题,并使用我现有的代码库运行此代码。 除了我在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);
});
});
}
}
});
获取工作示例: 克隆回购。 在这个repo中,应用程序使用v0.13.2
,你使用的v14.0.2
通过npm i graphql
安装的npm i graphql
。 降级graphql
到v0.13.2
。
我使用ID
,它工作正常! 你的问题的原因不是id的类型! 这是因为你提供了错误的值: ObjectID('actuall id')
为了解决这个问题,请为每个获取的数据调用toJson
函数,或者只是添加如下的虚拟id
:
YourSchema.virtual('id').get(function() {
return this.toJSON()._id
}
所以我刚发现_id
是ObjectID
类型,但似乎隐式地转换为String
。 因此,如果您将mongoose模型id类型定义为String
而不是mongoose.Schema.Types.ObjectId
那么它应该可以工作。 使用将_id复制到id的当前代码(来自compose.com教程),结果将是Mongo(保存后),_id将是ObjectID
类型,您的模型ID将是string类型。
换句话说,而不是这个
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
做这个
const Account = mongoose.model('Account', new mongoose.Schema({
id: String,
name: String
}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.