猫鼬+ GraphQL无法填充模型

时间:2020-02-05 16:26:25

标签: javascript mongodb mongoose graphql apollo-server

好吧,我知道关于此问题有很多问题,但是他们的解决方案都不适合我,或者我找不到正在发生的事情。

我有一个在本地主机上运行Apollo Server + Mongoose的后端服务器。我的问题是,自从我得到以下信息后,我就无法填充或创建集合:

错误"ID cannot represent value: <Buffer 5e 38 65 18 f1 e3 f5 43 10 d4 c1 45>"

这是模型:

import mongoose from 'mongoose';
const Float = require('mongoose-float').loadType(mongoose);

const gastoSchema = new mongoose.Schema({
    descripcion: String,
    importe: Float,
    proveedor: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Proveedor'
    },
}, {
    timestamps: {
        createdAt: 'fechaCreacion',
        updatedAt: 'fechaActualizacion'
    }
});

export default mongoose.model('gastos', gastoSchema);

这是我的类型定义:

import { gql } from 'apollo-server';

export default gql`
    type Gasto {
        id: ID
        descripcion: String
        importe: Float
        proveedor: Proveedor
    }

    extend type Query {
        gastos: [Gasto]
        gasto(id: ID!): Gasto
    }

    extend type Mutation {
        crearGasto(descripcion: String, importe: Float, proveedor: ID): Gasto
        actualizarGasto(id: ID!, descripcion: String, importe: Float, proveedor: ID): Gasto
        eliminarGasto(id: ID!): String
    }
`;

这是我的解析器:

import Gasto from '../models/Gasto';

export default {
    Query: {
        gastos: () => Gasto.find().populate('proveedores').exec(),
        gasto: (_, { id }) => Gasto.findById(id).populate('proveedores').exec()
    },
    Mutation: {
        crearGasto: (_, input) => Gasto.create(input),
        actualizarGasto: (_, input) => Gasto.findOneAndUpdate(input),
        eliminarGasto: (_, { id }) => Gasto.findOneAndDelete(id)
    }
};

尝试1

我已经在模型定义上尝试了此更改,但没有成功:

import mongoose from 'mongoose';
const Float = require('mongoose-float').loadType(mongoose);
const ObjectId = require('mongoose').Types.ObjectId;

ObjectId.prototype.valueOf = function() { return this.toString(); }

const gastoSchema = new mongoose.Schema({
    descripcion: String,
    importe: Float,
    proveedor: {
        type: ObjectId,
        ref: 'Proveedor'
    },
}, {
    timestamps: {
        createdAt: 'fechaCreacion',
        updatedAt: 'fechaActualizacion'
    }
});

export default mongoose.model('gastos', gastoSchema);

尝试2

根据mongoose documentation,我还尝试在populate('proveedores')(复数),populate('proveedor') (singular)之间进行切换,但错误发生了变化:

import Gasto from '../models/Gasto';

export default {
    Query: {
        gastos: () => Gasto.find({}).populate('proveedor').exec(),
        gasto: (_, { id }) => Gasto.findById(id).populate('proveedor').exec()
    },
    Mutation: {
        crearGasto: (_, input) => Gasto.create(input),
        actualizarGasto: (_, input) => Gasto.findOneAndUpdate(input),
        eliminarGasto: (_, { id }) => Gasto.findOneAndDelete(id)
    }
};

错误"message": "Schema hasn't been registered for model \"Proveedor\".\nUse mongoose.model(name, schema)"

以防万一,这是我的Proveedor模型定义:

import mongoose from 'mongoose';

const proveedorSchema = new mongoose.Schema({
    nombre: {
        type: String,
        required: true
    },
    telefono: String,
    direccion: String,
    email: String,
}, {
    timestamps: {
        createdAt: 'fechaCreacion',
        updatedAt: 'fechaActualizacion'
    }
});

export default mongoose.model('proveedores', proveedorSchema);

这是我在GraphQL游乐场上查询的内容:

query {
  gastos {
    id
    importe
    proveedor {
      id
      nombre
    }
  }
}

有任何线索吗?预先感谢。

1 个答案:

答案 0 :(得分:0)

mongoose.model()的第一个参数必须为the singular name of the collection your model is for. Mongoose automatically looks for the plural, lowercased version of your model name,因此对于您的情况:

mongoose.model('Gasto', gastoSchema);
mongoose.model('Proveedor', proveedorSchema);

接下来,您必须为proveedor字段和.exec()添加一个解析器以执行猫鼬查询

import Gasto from '../models/Gasto';
import Proveedor from '../models/Proveedor';

export default {

export default {
  Gasto: {
    proveedor: ({ proveedor }) => Proveedor.findById(proveedor).exec() 
  },
  Query: {
    gastos: () => Gasto.find().exec(),
    gasto: (_, { id }) => Gasto.findById(id).exec()
  },
  Mutation: {
    crearGasto: (_, input) => Gasto.create(input).exec(),
    actualizarGasto: (_, input) => (_, { id: _id, ...input }) => 
    Gasto.findOneAndUpdate({ _id }, input, { new: true }).exec(),
    eliminarGasto: (_, { id: _id }) => Gasto.findOneAndDelete({ _id }).exec()
  }
}

请注意,actualizarGasto的解析器必须为

actualizarGasto: (_, { id: _id, ...input }) => Gasto.findOneAndUpdate({ _id }, input, { new: true }).exec()