Koa.js与MongoDB集成与数据建模
MongoDB 与 Koa 的优势
MongoDB 是最流行的 NoSQL 数据库之一,其灵活的文档结构非常适合快速迭代的 Web 开发。与 Koa.js 结合,可以快速构建高性能的 RESTful API。本文将详细介绍如何在 Koa 项目中集成 MongoDB,并进行合理的数据建模。
依赖安装与连接
npm install mongoose koa-mount
// db.js - 数据库连接配置
const mongoose = require('mongoose');
const connectDB = async () => {
try {
await mongoose.connect('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true,
maxPoolSize: 10,
minPoolSize: 2
});
console.log('MongoDB 连接成功');
} catch (error) {
console.error('MongoDB 连接失败:', error);
}
};
module.exports = connectDB;
Mongoose 模型设计
| 字段类型 | 说明 | 示例 |
|---|---|---|
| String | 字符串类型 | 用户名、标题 |
| Number | 数字类型 | 价格、数量 |
| Date | 日期类型 | 创建时间 |
| Boolean | 布尔类型 | 状态标识 |
| ObjectId | 关联文档 | 用户ID、分类ID |
模型定义示例
// models/Product.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
name: {
type: String,
required: true,
trim: true,
maxlength: 100
},
price: {
type: Number,
required: true,
min: 0
},
category: {
type: Schema.Types.ObjectId,
ref: 'Category'
},
tags: [String],
stock: {
type: Number,
default: 0,
min: 0
},
isActive: {
type: Boolean,
default: true
},
createdAt: {
type: Date,
default: Date.now
}
}, {
timestamps: true,
versionKey: false
});
// 索引优化
ProductSchema.index({ category: 1, isActive: 1 });
ProductSchema.index({ price: 1 });
ProductSchema.index({ name: 'text', tags: 'text' });
module.exports = mongoose.model('Product', ProductSchema);
在 Koa 中使用模型
// routes/products.js
const Router = require('koa-router');
const Product = require('../models/Product');
const router = new Router({ prefix: '/api/products' });
// 获取产品列表
router.get('/', async (ctx) => {
const { page = 1, limit = 10, category } = ctx.query;
const query = { isActive: true };
if (category) query.category = category;
const products = await Product.find(query)
.populate('category', 'name')
.skip((page - 1) * limit)
.limit(Number(limit))
.sort({ createdAt: -1 });
const total = await Product.countDocuments(query);
ctx.body = {
data: products,
pagination: { total, page: Number(page), limit: Number(limit) }
};
});
// 创建产品
router.post('/', async (ctx) => {
const product = new Product(ctx.request.body);
await product.save();
ctx.status = 201;
ctx.body = product;
});
// 获取单个产品
router.get('/:id', async (ctx) => {
const product = await Product.findById(ctx.params.id).populate('category');
if (!product) {
ctx.status = 404;
ctx.body = { error: '产品不存在' };
return;
}
ctx.body = product;
});
module.exports = router;
聚合查询实战
- 分类统计:按分类统计产品数量和销售总额
- 价格区间:按价格区间分组统计产品分布
- 趋势分析:按日期统计销售额变化趋势
- 排行榜:获取销量最高的热销产品