【问题标题】:Graphql returns null id for mongoose aggregation queryGraphql 为 mongoose 聚合查询返回 null id
【发布时间】:2020-01-29 16:40:16
【问题描述】:

Graphql 为 mongoose 聚合查询返回 null id,但其他 mongoose 查询工作正常。

这是我的猫鼬模式:

const { Schema } = mongoose;
const ObjectId = Schema.Types.ObjectId;

const productSchema = new Schema({
  _id: ObjectId,
  price: Number
})

const Product = mongoose.model('Product', productSchema, 'Product')

这是我的 Graphql 架构:

type Product {
    id: ID
    price: String
}

Graphql 普通查询:

   context.Product.findOne()

console.log 的结果:

[ {
    price: 10,    
    _id: 5d7f8efebff791dcd3bb1b69
}]

graphql 的结果:

 "getSearch": [
      {
        "id": "5d7f8efebff791dcd3bb1b69",
        "price": 10,
  }]

这里一切都很好。 现在问题在于聚合查询:

GraphQL 查询:

context.Product.aggregate(
          [
            { $sample: { size: 1 } }
          ]
    )

console.log 的结果:

[ { _id: 5d7f8f23bff791dcd3bb1da3,
    price: 5
}]

GraphQL 的结果:

 "test": [
          {
            "id": null",
            "price": 7,
      }]

这里的问题是:

  • id 为空
  • console.log 和 graphql 的响应是不同的对象

【问题讨论】:

    标签: mongodb mongoose graphql aggregation-framework apollo-server


    【解决方案1】:

    MongoDB 中的文档通常没有id 属性,只有_id 属性。这显示在您看到的控制台输出中。但是,猫鼬模型实例确实有一个用于 id 的 getter,它返回 id 的值。 From the docs:

    默认情况下,Mongoose 会为您的每个模式分配一个 id 虚拟 getter,它将文档 _id 字段转换为字符串,或者在 ObjectIds 的情况下,返回其 hexString。

    findfindOne 等方法返回的内容是具有此 getter 的 Model 的实例。但是,使用 aggregate 会导致返回纯 JavaScript 对象(没有 getter)。

    您可以为id 字段编写解析器以从id_id 中提取值:

    function resolve (parent, args, context, info) {
      return parent.id || parent._id
    }
    

    【讨论】:

    • 没有理由这会以某种方式干扰 Apollo 客户端的缓存重定向。如果是这样,那么这是您如何实现 cacheRedirects 的问题。
    【解决方案2】:

    如果您不想更改它的每个实例,只需添加两个 ID。

    type Product {
      id: ID
      _id: ID
      price: String
    }
    

    【讨论】:

      【解决方案3】:

      如果您将猫鼬与nest jsGraphQL 一起使用,我已通过将id 更改为_id 并删除它上面的@prop Example on github 来修复它

        @Prop()//remove this
        @Field(() => ID,{ nullable: true })
        _id: string;
      

      【讨论】:

        【解决方案4】:

        id 元素添加到结果中对我来说效果很好

           const res = await Product.aggregate(
                  [
                    { $sample: { size: 1 } }
                  ]
            )
            res.forEach(element => {
                 element.id = element._id 
            });
            return res;
        

        【讨论】:

          猜你喜欢
          • 2020-05-19
          • 2020-10-01
          • 2020-06-06
          • 2019-03-08
          • 2018-10-26
          • 1970-01-01
          • 2019-06-14
          • 2020-01-07
          • 2020-03-01
          相关资源
          最近更新 更多