遵循本教程,我有一个猫鼬模型:(我使用术语“account”而不是“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
这是由最近引入的graphql包的更改引起的,有一个PR正在等待merge来解决它。
我没有发现问题,就用我现有的一个代码库运行了这段代码。只是我将变异包装在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);
});
});
}
}
});
获取工作示例:克隆回购。在此回购中,应用程序使用v0.13.2
,而您使用的是通过NPM i GraphQL
安装的v14.0.2
。将GraphQL
降级到v0.13.2
。
我使用了id
,它工作得很好!问题的原因不是ID的类型!这是因为您为它提供了错误的值:objectid('actuallid')
为了解决这个问题,为每个获取的数据调用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
}));