【问题标题】:getting different data from db than in GraphiQL从 db 获取与 GraphiQL 不同的数据
【发布时间】:2019-07-20 06:46:07
【问题描述】:

我是 graphQL 和 mongoDB 的新手,我正在尝试让它在我的项目中工作。问题在于 GraphiQL 中来自查询的数据与来自客户端内部相同查询的数据完全不同。这是我的架构设置:

const graphql = require('graphql');
const _ = require('lodash');
const Item = require('../models/item');
const {
  GraphQLObjectType,
  GraphQLString,
  GraphQLSchema,
  GraphQLID,
  GraphQLInt,
  GraphQLList
} = graphql;

const ItemType = new GraphQLObjectType({
  name: 'Item',
  fields: () => ({
    name: {
      type: GraphQLString
    },
    id: {
      type: GraphQLID
    },
    description: {
      type: GraphQLString
    },
    price: {
      type: GraphQLInt
    },
    image: {
      type: GraphQLString
    },
    category: {
      type: GraphQLString
    }
  })
});

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    item: {
      type: ItemType,
      args: {
        id: {
          type: GraphQLID
        }
      },
      resolve(parent, args) {
        // code to get data from db / other source
        return Item.findById(args.id);
      }
    },
    items: {
      type: new GraphQLList(ItemType),
      resolve(parent, args) {
        return Item.find({})
      }
    }
  }
});

当我从 graphiQL 对我收到的所有项目和数据进行查询时,是“正确的”。看起来像这样:

当我像这样从前端执行相同的确切查询时: 从“apollo-boost”导入 { gql };

const getItemsQuery = gql`
  {
    items {
      name
      id
      description
      price
      image
      category
    }
  }
`;

export { getItemsQuery };

数据如下所示:

看起来它一遍又一遍地重复第一项,我不明白为什么。 DB 也显示正确的项目。我的服务器端代码可以在这里找到:https://github.com/KamilStaszewski/shoppy/tree/adding_graphQL/server

【问题讨论】:

  • 确实很奇怪。应该是客户端的问题。也许这与您在 React 应用程序中使用查询的方式有关,您可以链接我在您的 github 中发生的文件或将其包含在您的帖子中吗?找不到(可能是你没推送)
  • 这看起来像是一个缓存问题。您使用的是 ApolloCache 的自定义实例吗?您可以发布您的客户端配置吗?
  • 我是新手,所以我不认为我正在使用 apollocache 的自定义实例。一切都是默认的。如果您的意思是我的客户端配置,那么 create-react-app 和 mongodbatlast 具有默认配置。
  • 能否显示您对items 进行查询调用的位置并设置性能

标签: reactjs mongodb graphql


【解决方案1】:

来自the docs

InMemoryCache 通过将结果拆分为单个对象、为每个对象创建唯一标识符并将这些对象存储在扁平数据结构中,在将数据保存到存储之前对其进行规范化。默认情况下,InMemoryCache 将尝试使用常见的 id 和 _id 主键作为唯一标识符,如果它们与对象上的 __typename 一起存在。

换句话说,Apollo 将同时使用__typenameid 为您获取的每个Item 创建一个缓存键。此键用于从缓存中获取适当的项目。问题是您的项目正在为他们的id 返回null。这导致每个项目都使用相同的键写入。因此,当您的查询结果从缓存中返回时,它会为您的 items 数组中的每个项目查找相同的键。

要解决此问题,您需要确保您的 API 返回 id 的值。我没有和猫鼬合作过那么多,但我认为由于猫鼬会根据_id 自动为你添加一个id 字段,因此只需从你的猫鼬模型中删除id 就足够了(不是你的GraphQL类型)。或者,您可以尝试将解析函数添加到 GraphQL 类型中的 id 字段:

resolve: (item) => item._id.toString()

【讨论】:

  • 谢谢。会检查出来。
  • 你是对的。在我从我的猫鼬模型中删除 id 属性后,props 是从 graphQL 正确传递的。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多