请求Unsplash/RandomUser API填充MongoDB仅插入22条数据如何解决
问题根因
写入中断的核心原因有3个:
- Unsplash随机图片接口的
count参数最大支持值为30,传入51时接口不会返回足额51条数据。循环执行到超过接口返回数组长度的索引时,imagedata[i]值为undefined,读取其description、urls等属性会直接抛出类型错误,中断整个写入流程,这也是仅写入22条就进入catch逻辑的核心原因。 - 现有
try/catch块没有接收错误实例,只会打印固定失败提示,无法定位具体报错位置;且两个外部API请求写在try块外,API请求失败(比如限流、网络超时)时不会被捕获。 - 循环条件写为
i < 50,就算接口返回足额51条数据,也只会遍历前50条,不符合写入51条的预期;同时Unsplash返回的图片数据中description字段经常为null,没有兜底值时可能触发MongoDB Schema校验错误。
修复方案
- 将所有异步逻辑(含API请求)移入
try块,catch块接收错误对象打印具体报错信息,方便排查问题 - 分两次请求Unsplash接口,分别拉取30条、21条数据凑够51张图片,避开count参数的上限限制
- 修正循环边界为
i < 51,匹配待写入的总条数 - 给可能为null的字段加空值兜底,避免读取属性报错或Schema校验失败
- 用
insertMany批量写入代替循环单条save,提升写入效率
修复后的完整代码如下:
const seeddata = async () => { try { // 清空集合原有数据 await MemoModel.deleteMany({}); // 拉取RandomUser用户数据 const userRes = await axios.get("https://randomuser.me/api/?results=51"); const userarr = userRes.data.results; // 分两次拉取Unsplash图片,规避count最大30的限制 const imgRes1 = await axios.get( "https://api.unsplash.com/photos/random/?count=30&client_id=GWDzPpjHk743C2QnVBRxu8PtmOI3npF5sePZZ7o0pg4" ); const imgRes2 = await axios.get( "https://api.unsplash.com/photos/random/?count=21&client_id=GWDzPpjHk743C2QnVBRxu8PtmOI3npF5sePZZ7o0pg4" ); const imagedata = [...imgRes1.data, ...imgRes2.data]; // 提前校验接口返回数据长度,避免越界 if (userarr.length !== 51 || imagedata.length !== 51) { throw new Error(`接口返回数据长度不足,用户数:${userarr.length},图片数:${imagedata.length}`); } // 批量构造待写入文档 const insertList = []; for (let i = 0; i < 51; i++) { const user = userarr[i]; const img = imagedata[i]; insertList.push({ name: { firstname: user.name.first, lastname: user.name.last, username: user.login.username, }, about: { user: `${user.gender} aged ${user.dob.age}. Rotting here for ${user.registered.age} `, }, location: { country: countryarr[Math.floor(Math.random() * countryarr.length)], state: user.location.state, city: user.location.city, address: `${user.location.street.name} ,${user.location.street.number}`, zipcode: user.location.postcode, }, email: { user: user.email, }, image: { dp: user.picture.large, coverimage: "https://source.unsplash.com/random/?mountains", }, posts: { postno: i, // description为null时用空字符串兜底 posttitle: img.description || "", postcontent: img.urls.regular, postlikesno: img.likes, postcommentno: img.width, }, }); } // 批量写入数据 await MemoModel.insertMany(insertList); console.log("51条数据全部写入成功"); } catch (err) { // 打印具体错误信息 console.log("数据写入失败:", err.message); } }; seeddata().then(() => { mongoose.connection.close(); });
额外说明:如果后续需要写入更大批量的测试数据,建议给Unsplash请求加延迟,避免触发接口频率限制。
内容的提问来源于stack exchange,提问作者Kartic Joshi
相关产品推荐
相关产品推荐

