Какой правильный тип использовать для поля ObjectId в mongoose и GraphQL? - PullRequest
0 голосов
/ 09 сентября 2018

После этого урока , у меня есть модель мангуста: (я использую термин "Аккаунт" вместо "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:

From MongoDB Compass showing created object

но, похоже, проблема с чтением значения.

Насколько совместимы GraphQLID и mongoose.Schema.Types.ObjectId? Если они не совместимы, я неправильно понимаю учебник, в частности, его использование:

newAccount.id = newAccount._id;

? Я не могу сказать, генерируется ли ошибка с помощью GraphQL, или MongoDB, или Mongoose, или чего-то еще.

EDIT

Любая информация об ошибке

ID не может представлять значение: {_bsontype: \ "ObjectID \", id:}

было бы очень полезно. Я чувствую, что он говорит мне, что не может сериализовать объект BSON ... но затем он отображает его сериализацию. Даже знание того, какая технология (mongo? Mongoose? Graphql?) Генерирует ошибку, поможет. Мне не повезло с Google.

РЕДАКТИРОВАТЬ 2

Это было вызвано изменением недавно введенного пакета graphql, и PR ожидает слияния, которое разрешает его.

Ответы [ 3 ]

0 голосов
/ 09 сентября 2018

Я использовал ID и все работает отлично! причина вашей проблемы не в идентификаторе типа! это потому что вы указали неверное значение: ObjectID('actuall id')

Чтобы решить эту проблему, вызовите функцию toJson для каждой выбранной информации или просто добавьте виртуальную id, например:

YourSchema.virtual('id').get(function() {
    return this.toJSON()._id
}
0 голосов
/ 22 сентября 2018

Итак, я только что обнаружил, что _id имеет тип ObjectID, но, похоже, неявно приведен к String. Так что, если вы определили тип идентификатора модели mongoose как String вместо mongoose.Schema.Types.ObjectId, он должен работать. Используя ваш текущий код (из учебника compose.com), который копирует _id в id, в результате будет получено, что в Mongo (после сохранения) _id будет иметь тип ObjectID, а идентификатор вашей модели будет иметь тип 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
}));
0 голосов
/ 09 сентября 2018

Я не нашел проблему и запустил этот код с одной из моих существующих баз кода. За исключением того, что я завернул мутацию в 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, а вы используете v14.0.2, установленный через npm i graphql. Понижение graphql до v0.13.2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...