【问题标题】:Mongoose + GraphQL cannot populate model [duplicate]Mongoose + GraphQL 无法填充模型 [重复]
【发布时间】:2020-05-21 14:52:45
【问题描述】:

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

我有一个在本地主机上运行 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
    }
  }
}

有什么线索吗?提前致谢。

【问题讨论】:

  • 完成...没有任何改变。
  • 请参阅链接帖子中提供的答案。您也可以为每个 id 字段添加一个解析器,例如 obj => obj._id.toString()

标签: javascript mongodb mongoose graphql apollo-server


【解决方案1】:

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() 添加解析器以执行 mongoose 查询

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()

【讨论】:

    猜你喜欢
    • 2014-11-27
    • 2020-02-28
    • 2013-12-24
    • 2017-03-23
    • 2017-05-15
    • 2016-07-11
    • 2019-01-15
    • 2018-12-12
    • 2021-02-28
    相关资源
    最近更新 更多