KOA技术分享

专注 Koa.js 框架的编程知识分享

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;

聚合查询实战

← 下一篇:Koa.js GraphQL API 开发实战 下一篇:Koa.js 缓存策略与Redis集成 →