新版Mongoose使用遇困:Express接口返回MongoDB全部产品问题求助
解决Mongoose查询全量数据的异步问题与Express接口优化
我来帮你搞定新版Mongoose里的查询问题,还有你觉得Model.find()繁琐的痛点:
第一步:给Product模型补全正确的全量查询方法
你的product.js里还没有getAllProductListings这个方法,我们给Schema加个静态方法来封装查询逻辑,利用新版Mongoose默认支持的Promise特性:
'use strict'; var mongoose = require('mongoose'); // Product Schema var ProductSchema = mongoose.Schema({ category: { type: String, index: true }, name: { type: String, required: true }, // 补充你的其他字段... }); // 添加静态方法:获取所有产品列表 ProductSchema.statics.getAllProductListings = function() { // 空对象参数表示查询所有文档,返回的是thenable的Query对象 return this.find({}); }; // 编译并导出模型 var Product = mongoose.model('Product', ProductSchema); module.exports = Product;
第二步:修正Express路由的异步逻辑
你原来的路由是同步赋值,这肯定拿不到数据——Mongoose查询是异步的,得用async/await或者.then()来处理结果:
// Get latest listings router.get('/latest/all', async function (req, res, next) { try { // 用await等待查询结果返回 const products = await Product.getAllProductListings(); // 用res.json()比res.send()更适合返回JSON格式数据 res.json(products); } catch (err) { // 捕获查询错误,交给Express的错误处理中间件处理 next(err); } });
为什么原来的代码出问题?
- 新版Mongoose里,
Model.find()如果不传回调函数,返回的是Query对象,不是直接的查询结果。这个对象是thenable的,必须通过await或者.then()才能触发查询并拿到实际数据。 - 你原代码里同步赋值
var json = Product.getAllProductListings();,拿到的只是Query对象,不是产品数据,所以前端会收到不符合预期的内容。
更简洁的替代写法(不用封装方法)
如果只是简单的全量查询,也可以直接在路由里写,省掉额外的方法封装:
router.get('/latest/all', async (req, res, next) => { try { const products = await Product.find({}); res.json(products); } catch (err) { next(err); } });
内容的提问来源于stack exchange,提问作者Joe Early
相关产品推荐
相关产品推荐

