使用Mongoose向MongoDB Atlas执行insertMany时遇primitive.D错误
Mongoose批量插入MongoDB Atlas报错:MongoBulkWriteError: Expected 'insert' to be string, but got primitive.D instead.
执行Mongoose的insertMany批量插入操作时触发以下错误:
MongoBulkWriteError: Expected 'insert' to be string, but got primitive.D instead.
已尝试在Mongoose连接选项中设置retryWrites: false禁用重试写入,但问题未解决。
相关代码及信息
1. Mongoose连接配置
// Mongoose connection options const mongooseOptions = { retryWrites: false, }; mongoose.connect(mongoURI, mongooseOptions);
2. 初始接口代码
router.post('/insertMany', async (req, res) => { try { console.log(req.body); const category = await Category.insertMany(req.body.list); res.json(category); } catch (error) { console.log(error); res.status(400).json({ error: error.message }); } });
3. 修改后的接口代码
router.post('/insertMany', async (req, res) => { try { console.log(req.body); let list = req.body.list.map(cat => Category(cat)) const category = await Category.insertMany(list); res.json(category); } catch (error) { console.log(error); res.status(400).json({ error: error.message }); } });
4. Postman请求体
{ "list": [ { "name": "Test Category", "description": "Test category Desc" } ] }
5. 错误日志
Incoming POST request to /category/insertMany { list: [ { name: 'Test Category', description: 'Test category Desc' } ] } MongoBulkWriteError: Expected 'insert' to be string, but got primitive.D instead. Doc = [{insert [{collection category}]} {documents [[{name Test Category} {active true} {description Test category Desc} {_id ObjectID("65e19ac0e6f006f0730df049")} {__v 0}]]} {ordered true} {writeConcern [{w majority}]} {lsid [{id {4 [20 207 50 38 60 101 78 182 181 103 131 17 48 167 185 124]}}]} {$clusterTime [{clusterTime {1709283559 1}} {signature [{hash {0 [143 10 169 77 44 6 244 27 189 31 40 244 125 245 89 91 153 147 30 152]}} {keyId 7285440633500598274}]}]} {$db desejo}] at resultHandler (/Users/jayedumindu/Dev/Desejo-Ecommerce/Backend/node_modules/mongoose/node_modules/mongodb/lib/bulk/common.js:294:29) at /Users/jayedumindu/Dev/Desejo-Ecommerce/Backend/node_modules/mongoose/node_modules/mongodb/lib/utils.js:274:66 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { ok: 0, code: 8000, codeName: 'AtlasError', writeErrors: [], result: BulkWriteResult { insertedCount: 0, matchedCount: 0, modifiedCount: 0, deletedCount: 0, upsertedCount: 0, upsertedIds: {}, insertedIds: { '0': new ObjectId('65e19ac0e6f006f0730df049') } }, insertedDocs: [ { name: 'Test Category', active: true, description: 'Test category Desc', _id: new ObjectId('65e19ac0e6f006f0730df049'), __v: 0 } ], [Symbol(errorLabels)]: Set(0) {} }
6. Category模型定义
// models/Category.js const mongoose = require('mongoose'); const categorySchema = new mongoose.Schema({ name: { type: String, unique: true }, active: { type: Boolean, default: true }, // Added for tracking the active status description: String }); module.exports = mongoose.model('Category', categorySchema, { collection: 'category' });
错误原因分析
错误日志中显示insert字段被传入了嵌套对象[{collection category}],而MongoDB的批量插入命令要求insert的值是字符串类型的集合名。问题出在Category模型的导出代码:
mongoose.model()的第三个参数如果是对象,会被识别为模型选项,而非集合名。当前代码传入{ collection: 'category' }作为第三个参数,导致Mongoose内部生成批量插入命令时,错误地将集合名处理成了对象结构,最终触发primitive.D类型错误。
解决方法
修改Category模型的导出代码,将第三个参数直接传入字符串类型的集合名'category',而非对象:
// models/Category.js const mongoose = require('mongoose'); const categorySchema = new mongoose.Schema({ name: { type: String, unique: true }, active: { type: Boolean, default: true }, // Added for tracking the active status description: String }); // 第三个参数直接传集合名字符串 module.exports = mongoose.model('Category', categorySchema, 'category');
另外,修改后的接口代码中list = req.body.list.map(cat => Category(cat))这一步是多余的,insertMany可以直接接收普通对象数组,因此可以改回初始的接口代码,也可以保留,不影响功能。
内容的提问来源于stack exchange,提问作者Dumindu Jayasekara
相关产品推荐
相关产品推荐

