新版Node.js中使用forEach遍历MongoDB查询结果报错求助
解决Mongoose中
find().forEach报错的问题 问题重现
尝试通过forEach配合find从MongoDB数据库中仅提取汽车名称时,出现以下错误:
TypeError: Car.find(...).forEach is not a function
代码已成功连接本地数据库,能完整输出数据库内容,但提取名称时失败。此前尝试过回调函数,但新版MongoDB已不再支持该写法。
完整代码如下:
const mongoose = require('mongoose'); const express = require('express'); const app = express(); mongoose.connect("mongodb://127.0.0.1:27017/carsDB",{useNewUrlParser:true, useUnifiedTopology:true}); const carSchema = new mongoose.Schema({ name: String, year: Number, make:String }); const Car = mongoose.model("car", carSchema); const elantra = new Car({ name: "Elanta", year: 2020, make: "Hyundai" }); const civic = new Car({ name: "Civic Sport", year: 2023, make: "Honda" }); Car.insertMany([elantra,civic]); Car.find().forEach((car)=>{ console.log(car.name); });
错误原因
- Mongoose的
find()方法返回的是Query对象,不是直接的文档数组,因此没有forEach方法,必须先将Query解析为实际的数组才能遍历。 insertMany和find都是异步操作,原代码没有处理异步顺序,可能出现查询执行时数据还未插入完成的情况。
解决方案
方法1:使用async/await(推荐)
将所有异步操作包裹在async函数中,通过await等待操作完成,确保顺序执行:
const mongoose = require('mongoose'); const express = require('express'); const app = express(); async function run() { // 等待数据库连接成功 await mongoose.connect("mongodb://127.0.0.1:27017/carsDB",{useNewUrlParser:true, useUnifiedTopology:true}); const carSchema = new mongoose.Schema({ name: String, year: Number, make: String }); const Car = mongoose.model("car", carSchema); const elantra = new Car({ name: "Elantra", year: 2020, make: "Hyundai" }); const civic = new Car({ name: "Civic Sport", year: 2023, make: "Honda" }); // 等待数据插入完成 await Car.insertMany([elantra,civic]); // 等待查询结果,得到文档数组 const cars = await Car.find(); // 对数组执行forEach遍历 cars.forEach((car)=>{ console.log(car.name); }); } // 执行函数并捕获错误 run().catch(err => console.error(err));
方法2:使用Promise链式调用
如果不喜欢async/await,可以通过then()链式处理异步操作:
const mongoose = require('mongoose'); const express = require('express'); const app = express(); mongoose.connect("mongodb://127.0.0.1:27017/carsDB",{useNewUrlParser:true, useUnifiedTopology:true}) .then(() => { const carSchema = new mongoose.Schema({ name: String, year: Number, make: String }); const Car = mongoose.model("car", carSchema); const elantra = new Car({ name: "Elantra", year: 2020, make: "Hyundai" }); const civic = new Car({ name: "Civic Sport", year: 2023, make: "Honda" }); return Car.insertMany([elantra,civic]); }) .then(() => { // 查询获取文档数组 return Car.find(); }) .then(cars => { // 遍历数组输出名称 cars.forEach(car => console.log(car.name)); }) .catch(err => console.error(err));
额外优化:仅查询所需字段
如果只需要汽车名称,可以在find中指定投影,减少不必要的数据传输:
// 仅返回name字段,不返回_id const cars = await Car.find({}, {name: 1, _id: 0}); // 或者简写 const cars = await Car.find({}, 'name');
内容的提问来源于stack exchange,提问作者Harmanjit Singh
相关产品推荐
相关产品推荐

