Mongoose bulkWrite报错:无法读取null的insertOne属性排查
MongoDB bulkWrite 触发 TypeError 问题排查
问题详情
操作MongoDB时触发TypeError: Cannot read properties of null (reading 'insertOne')。已确认state.id.slice返回string类型,且存在满足state.id.slice(0, 3) == "FBL"条件的对象;但将条件改为if (1 === 1){...}时,代码可正常运行,求问题原因。
相关代码
import States from "./models/states.js"; import { connectToDB } from "./utils/database.js"; export default async function updateStates(states) { await connectToDB(); const bulkwrite = await states.map((state) => { if (state.id.slice(0, 3) == "FBL") { return { updateMany: { filter: { id: state.id }, update: state, upsert: true, }, }; } return null; }); const res = await States.bulkWrite(bulkwrite); }
完整报错信息
/Users/tung/project/sk/mongo_db/node_modules/mongoose/lib/helpers/model/castBulkWrite.js:24 if (op['insertOne']) { ^ TypeError: Cannot read properties of null (reading 'insertOne') at castBulkWrite (/Users/tung/project/sk/mongo_db/node_modules/mongoose/lib/helpers/model/castBulkWrite.js:24:9) at /Users/tung/project/sk/mongo_db/node_modules/mongoose/lib/model.js:3366:37 at Array.map (<anonymous>) at Function.bulkWrite (/Users/tung/project/sk/mongo_db/node_modules/mongoose/lib/model.js:3366:27) at updateStates (file:///Users/tung/project/sk/mongo_db/States.js:20:28) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Timeout.stateUpdate [as _onTimeout] (file:///Users/tung/project/sk/mongo_db/app.js:99:3)
问题原因
你的states.map()会返回包含null元素的数组——当state.id.slice(0,3)不等于"FBL"时,你返回了null。而mongoose的bulkWrite()要求传入的数组每一项都是有效的操作对象(比如包含updateMany的对象),它会遍历数组元素并尝试读取操作类型属性(比如insertOne),遇到null时就会触发"Cannot read properties of null"的错误。
当条件改成1===1时,所有元素都会返回有效的updateMany操作对象,数组里没有null,所以bulkWrite()能正常运行。另外,map()是同步数组方法,不需要加await,你之前的await states.map(...)是多余的,没有实际作用。
解决方案
在调用bulkWrite()前过滤掉数组中的null元素,同时去掉多余的await:
import States from "./models/states.js"; import { connectToDB } from "./utils/database.js"; export default async function updateStates(states) { await connectToDB(); const bulkwrite = states.map((state) => { if (state.id.slice(0, 3) == "FBL") { return { updateMany: { filter: { id: state.id }, update: state, upsert: true, }, }; } return null; }).filter(Boolean); // 过滤null、undefined等假值 const res = await States.bulkWrite(bulkwrite); }
filter(Boolean)会自动剔除数组中的假值,确保传入bulkWrite()的全是有效操作对象。
内容的提问来源于stack exchange,提问作者TungTung
相关产品推荐
相关产品推荐

