从db获得的数据与在GraphiQL中获得的数据不同

时间:2019-02-26 16:47:00

标签: reactjs mongodb graphql

我是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进行查询时,我收到的所有项目和数据都是“正确的”。看起来像这样:enter image description here

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

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

export { getItemsQuery };

数据如下: enter image description here

它似乎一遍又一遍地重复第一个项目,我不知道为什么。 DB也显示了正确的项目。我的服务器端代码可以在这里找到:https://github.com/KamilStaszewski/shoppy/tree/adding_graphQL/server enter image description here

1 个答案:

答案 0 :(得分:3)

来自the docs

  

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

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

要解决此问题,您需要确保您的API返回id的值。我使用猫鼬的工作还不多,但是我认为,由于猫鼬会根据id自动为您添加一个_id字段,因此只需从您的猫中删除id猫鼬模型(不是您的GraphQL类型)。或者,您可以尝试在GraphQL类型的id字段中添加一个resolve函数:

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