如何使用GraphQL将JavaScript文件中的数据插入MongoDB
解决方案:将现有商品数据插入MongoDB(GraphQL + MongoDB)
问题分析
你的代码存在几个关键问题:
createItemMutation定义的参数和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}`); }); };
验证方法
- 启动服务器后,访问Apollo Server的GraphQL Playground(默认是
http://localhost:4000) - 如果是手动调用Mutation:
- 单个插入:
mutation { createItem( name: "Test Item", aisle: "A1", bay: "B2", price: 9.99, xVal: 10, yVal: 20 ) { id name } } - 批量插入现有数据:
mutation { bulkInsertItems { id name aisle } }
- 单个插入:
- 调用Query验证数据是否存在:
query { items { id name price } }
关键注意事项
- 使用
insertOne插入单个文档,insertMany批量插入,替代已废弃的insert方法 - MongoDB自动生成的
_id会通过Itemresolver映射为id字段,符合GraphQL的ID类型要求 - 批量插入时建议添加重复检查,避免多次启动服务器重复插入数据
内容的提问来源于stack exchange,提问作者The_Green_Wizard
相关产品推荐
相关产品推荐

