GraphQL & Mongoose Schema - 如何将一组 mongoose objectId 引用存储到另一种类型?

Posted

技术标签:

【中文标题】GraphQL & Mongoose Schema - 如何将一组 mongoose objectId 引用存储到另一种类型?【英文标题】:GraphQL & Mongoose Schema - How to store an array of mongoose objectId references to another type? 【发布时间】:2021-02-25 23:52:18 【问题描述】:

我目前正在为我当地的比萨店开发比萨订购/跟踪系统。正如您在下面看到的,我定义了 GraphQL 类型和 Mongoose 模型。在我的比萨饼中,我设置了一系列浇头来引用浇头模型。我的问题是,我的突变定义和使用所需参数对该突变的调用是什么样的?

我希望 Mongoose 中的 Pizza 文档包含相关的 ToppingId,以便我可以引用该浇头的其他字段,例如名称和价格。希望这很清楚。也许数组不是解决这个问题的最佳方法??

如果在披萨模型中有更有效的浇头方法,请分享。

GraphQL 类型:

    type Topping 
        id: ID!
        name: String!
        price: Float!
        createdAt: String!
    
    type Pizza 
        id: ID!
        location: String!
        price: Float!
        toppings: [Topping]!
        createdAt: String!
        toppingCount: Int!
    

猫鼬模型:

const pizzaSchema = new Schema(
    location: String,
    price: Number,
    toppings: 
        type: Schema.Types.ObjectId,
        ref: "toppings"
    ,
    createdAt: String
);

const toppingSchema = new Schema(
    name: String,
    price: Number,
    createdAt: String
);

因此,理想情况下,在数据库中查看披萨时,它应该如下所示:

_id: ObjectId("5fab2e6cc4b5e628685228f6")
> toppings:Array
[
    ObjectId("5fab2e6cc4b5e628685228f7")
    ObjectId("5fab2e6cc4b5e628685228f8")
]
location:"Barcelona"
price:123
createdAt:"12"
__v:0

提前致谢。

编辑:我的突变类型和突变调用/Args + 错误消息

createPizza(pizzaInput: PizzaInput): Pizza!
input PizzaInput 
    location: String!
    price: Float!
    toppings: [ID]!
    createdAt: String!


mutation 
  createPizza(pizzaInput: 
    location:"Barcelona"
    price:12
    toppings: [
      "5faaca3129c74ff103d3ccaf"
      "5faaed887ac3c53010b8075b"
    ]
    createdAt:"AAAA"
  )
    id
    price
    location
    toppings 
      id
    
    createdAt
    toppingCount
  

错误信息: "ID 不能代表值:"

【问题讨论】:

【参考方案1】:

我相信您需要 PizzaSchema 中的 toppings 值来反映它是一个数组。目前,它只是被定义为这样的对象:

    toppings: 
        type: Schema.Types.ObjectId,
        ref: "toppings"
    ,

而不是(注意括号表示数组):

    toppings: [
        type: Schema.Types.ObjectId,
        ref: "toppings"
    ],

或者完整的,应该是这样的:

const pizzaSchema = new Schema(
    location: String,
    price: Number,
    toppings: [
        type: Schema.Types.ObjectId,
        ref: "toppings"
    ],
    createdAt: String
);

your edit之后更新:

您是否为 Pizza.toppings 定义了解析器?我猜你的解析器地图中缺少这样的东西:

  Pizza: 
    toppings: (parent) => 
      const obj_ids = parent.toppings.map((id) => ObjectId(id));
      return Topping.find( _id:  $in: obj_ids  );
    ,
  

我不是 GraphQL 专家,所以我不确定是否有更有效的方法在比萨模型中添加配料,但根据我添加的测试,上述解析器通过了“ID 不能代表价值” ...”问题。

【讨论】:

谢谢,我实际上是在发布后立即更改的。 GraphQL 突变会是什么样子?在 Playground 中调用突变会是什么样子?这真的是我坚持的:( @alanphil 您能否编辑您的问题以包括您尝试执行的突变类型、您当前尝试使用的内容以及您收到的错误消息? 问题已更新以包含请求! @alanphil 这将取决于您用于 GraphQL 服务器的内容(假设类似:express-graphql、apollo-server-express 等)。 经过一周的尝试解决此问题,我很感激你。解决方案:我创建了一个 Pizza.toppings 解析器,Pizza 现在有一个引用许多浇头的数组。

以上是关于GraphQL & Mongoose Schema - 如何将一组 mongoose objectId 引用存储到另一种类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 graphql 和 mongoose 进行突变

NestJS + Mongoose + GraphQL:“填充”不起作用

如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用

嵌套对象的模式/解析 graphql/mongoose

graphql + mongoose + typescript,如何减少重复的模型定义

嵌套的 Mongoose 查询数据未显示在 GraphQL 查询中