You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GraphQL将JavaScript文件中的数据插入MongoDB

解决方案:将现有商品数据插入MongoDB(GraphQL + MongoDB)

问题分析

你的代码存在几个关键问题:

  • createItem Mutation定义的参数和Item类型的字段不匹配,缺少bay、price等必填字段
  • Resolver里错误地将整个items数组作为单个文档插入,而非逐个插入或批量插入
  • 没有利用好现有itemsListData里的完整数据结构

修正步骤

1. 完善GraphQL类型定义

更新typeDefs,让Mutation支持单个商品插入(匹配Item所有字段)和批量商品插入(一次性导入现有数据):

const typeDefs = gql`
  type Query {
    items:[Item!]!
  }
  
  type Item{
    id:ID!,
    name:String!,
    aisle:String!,
    bay:String!,
    price:Float!,
    xVal:Int!,
    yVal:Int!
  }
  
  # 单个插入商品
  type Mutation {
    createItem(
      name: String!, 
      aisle: String!,
      bay: String!,
      price: Float!,
      xVal: Int!,
      yVal: Int!
    ): Item!
    
    # 批量插入现有商品数据
    bulkInsertItems: [Item!]!
  }
`;

2. 修正Resolver逻辑

更新resolvers,分别实现单个插入和批量插入的逻辑:

const resolvers = {
  Query: {
    items: async (_, __, { db }) => {
      // 从数据库查询商品,替代直接返回本地数组
      return await db.collection('Items').find().toArray();
    },
  },

  Item: {
    id: ({ _id, id }) => _id || id,
  },

  Mutation: {
    // 单个商品插入
    createItem: async (_, args, { db }) => {
      // args包含所有传入的商品字段
      const newItem = args;
      // 使用insertOne插入单个文档
      const result = await db.collection('Items').insertOne(newItem);
      // 返回插入后的文档(包含MongoDB自动生成的_id)
      return { ...newItem, id: result.insertedId };
    },

    // 批量插入现有itemsListData中的数据
    bulkInsertItems: async (_, __, { db }) => {
      // 先检查数据库是否已有数据,避免重复插入
      const existingCount = await db.collection('Items').countDocuments();
      if (existingCount > 0) {
        throw new Error('数据库中已有商品数据,请勿重复插入');
      }

      // 批量插入所有商品
      const result = await db.collection('Items').insertMany(items);
      // 返回插入的所有文档
      return items.map((item, index) => ({
        ...item,
        id: result.insertedIds[index]
      }));
    }
  }
};

3. 可选:服务器启动时自动初始化数据

如果希望服务器启动时自动导入现有数据(无需手动调用Mutation),可以在start函数中添加初始化逻辑:

const start = async () => {
  const client = new MongoClient("mongodb+srv://admin:admin@quickkartcluster.o0bsfej.mongodb.net/test", { useNewUrlParser: true, useUnifiedTopology: true });
  
  await client.connect();
  const db = client.db("QuickKart");

  // 初始化数据:仅当集合为空时插入
  const itemsCollection = db.collection('Items');
  const count = await itemsCollection.countDocuments();
  if (count === 0) {
    await itemsCollection.insertMany(items);
    console.log('✅ 现有商品数据已成功导入MongoDB');
  } else {
    console.log('ℹ️ 数据库中已有商品数据,跳过初始化');
  }

  const context = { db };

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    context,
    introspection: true
  }); 

  server.listen().then(({ url }) => {
    console.log(`🚀  Server ready at ${url}`);
  });
};

验证方法

  1. 启动服务器后,访问Apollo Server的GraphQL Playground(默认是http://localhost:4000)
  2. 如果是手动调用Mutation:
    • 单个插入:
      mutation {
        createItem(
          name: "Test Item",
          aisle: "A1",
          bay: "B2",
          price: 9.99,
          xVal: 10,
          yVal: 20
        ) {
          id
          name
        }
      }
      
    • 批量插入现有数据:
      mutation {
        bulkInsertItems {
          id
          name
          aisle
        }
      }
      
  3. 调用Query验证数据是否存在:
    query {
      items {
        id
        name
        price
      }
    }
    

关键注意事项

  • 使用insertOne插入单个文档,insertMany批量插入,替代已废弃的insert方法
  • MongoDB自动生成的_id会通过Item resolver映射为id字段,符合GraphQL的ID类型要求
  • 批量插入时建议添加重复检查,避免多次启动服务器重复插入数据

内容的提问来源于stack exchange,提问作者The_Green_Wizard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:25:36