从 db 获取与 GraphiQL 不同的数据

Posted

技术标签:

【中文标题】从 db 获取与 GraphiQL 不同的数据【英文标题】:getting different data from db than in 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 中发生的文件或将其包含在您的帖子中吗?找不到(可能是你没推送) 这里使用了查询:github.com/KamilStaszewski/shoppy/blob/adding_graphQL/client/…,来自它的数据被传递并映射到这个组件github.com/KamilStaszewski/shoppy/blob/adding_graphQL/client/… 这看起来像是一个缓存问题。您使用的是 ApolloCache 的自定义实例吗?您可以发布您的客户端配置吗? 我是新手,所以我不认为我正在使用 apollocache 的自定义实例。一切都是默认的。如果您的意思是我的客户端配置,那么 create-react-app 和 mongodbatlast 具有默认配置。 能否显示您对items 进行查询调用的位置并设置性能 【参考方案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 正确传递的。非常感谢。

以上是关于从 db 获取与 GraphiQL 不同的数据的主要内容,如果未能解决你的问题,请参考以下文章

GraphiQL在获取所有记录时返回空值[重复]

GraphQL 查询从 JSON 数据源返回 GraphiQL 和 App 中的空对象

从 Oracle DB 获取可滚动的结果集

从 db 获取数据到 js 数组

从同一个表但不同的数据库中获取一列连接

从Mongo DB嵌套数组中获取不同的值并输出到单个数组