简体   繁体   English

跨mongoose和GraphQL的ObjectId字段使用的正确类型是什么?

[英]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中看到它:

从MongoDB Compass显示创建的对象

but there seems to be a problem reading the value. 但阅读价值似乎有问题。

How compatible are GraphQLID and mongoose.Schema.Types.ObjectId ? 如何兼容是GraphQLIDmongoose.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 . 降级graphqlv0.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 . 所以我刚发现_idObjectID类型,但似乎隐式地转换为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.

相关问题 猫鼬模式混合类型字段错误地将ObjectId字段保存为字符串 - Mongoose schema mixed type field errantly saving ObjectId field as a String GraphQL &amp; Mongoose Schema - 如何将一组 mongoose objectId 引用存储到另一种类型? - GraphQL & Mongoose Schema - How to store an array of mongoose objectId references to another type? 当模式字段类型在Mongoose中为ObjectId时,属性ref是否必需? - Is property `ref` necessary when schema field type is `ObjectId` in Mongoose? 对 Type-graphql 和 Typeorm 实体中的外键字段使用 ID 标量类型在语义上是否正确? - Is it semantically correct to use ID scalar type for a foreign key field in a Type-graphql and Typeorm entity? 如何在Graphql模式中表示猫鼬的objectID数组 - How to represent an array of objectID of mongoose in Graphql Schema ObjectId字段的猫鼬唯一索引 - Mongoose unique index for ObjectId field Mongoose 填充没有ObjectId的字段? - Mongoose populate a field without ObjectId? 什么是Mongoose ODM的ObjectId? - What are Mongoose ODM's ObjectId? mongo ObjectID, ObjectId &amp; Mongoose ObjectId 有什么区别 - What is the difference between mongo ObjectID, ObjectId & Mongoose ObjectId 如何在 GraphQL 模式中使用“十进制”作为字段类型? - How to use 'Decimal' as a field type in GraphQL schema?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM