阿里云主机折上折
  • 微信号
Current Site:Index > MongoDB integration and ORM usage

MongoDB integration and ORM usage

Author:Chuan Chen 阅读数:65265人阅读 分类: Node.js

MongoDB Integration

MongoDB is a popular NoSQL database known for its flexibility and scalability. In Koa2, integrating MongoDB is typically achieved through the official mongodb driver or higher-level ODMs like mongoose. Below is a detailed comparison and implementation steps for both approaches.

Using the Native MongoDB Driver

The native driver provides the most direct interface for MongoDB operations, suitable for scenarios requiring fine-grained query control. First, install the dependency:

npm install mongodb

Typical database connection code:

const { MongoClient } = require('mongodb');
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);

async function connectDB() {
  try {
    await client.connect();
    console.log('Connected to MongoDB');
    return client.db('mydatabase');
  } catch (err) {
    console.error('Connection error:', err);
    process.exit(1);
  }
}

// Usage in Koa middleware
app.use(async (ctx, next) => {
  ctx.db = await connectDB();
  await next();
});

Basic CRUD operations example:

// Insert document
await ctx.db.collection('users').insertOne({
  name: 'Alice',
  age: 28,
  tags: ['developer', 'designer']
});

// Query document
const user = await ctx.db.collection('users')
  .findOne({ name: 'Alice' });

// Update document
await ctx.db.collection('users')
  .updateOne(
    { name: 'Alice' },
    { $set: { age: 29 } }
  );

Using Mongoose ODM

Mongoose offers advanced features like schema definition and data validation. Installation:

npm install mongoose

Typical connection and model definition:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/mydatabase');

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  age: { type: Number, min: 18 },
  createdAt: { type: Date, default: Date.now }
});

const User = mongoose.model('User', userSchema);

Usage example in Koa:

app.use(async ctx => {
  // Create document
  const newUser = await User.create({
    name: 'Bob',
    age: 25
  });

  // Query with conditions
  const users = await User
    .find({ age: { $gt: 20 } })
    .sort('-createdAt')
    .limit(10);
});

ORM Advanced Techniques

Transaction Handling

MongoDB 4.0+ supports multi-document transactions, crucial for atomic operations:

const session = await mongoose.startSession();
session.startTransaction();

try {
  await User.create([{
    name: 'Charlie',
    age: 30
  }], { session });

  await Account.create([{
    userId: '...',
    balance: 1000
  }], { session });

  await session.commitTransaction();
} catch (err) {
  await session.abortTransaction();
  throw err;
} finally {
  session.endSession();
}

Aggregation Pipeline

For complex data analysis, the aggregation pipeline is more powerful than simple queries:

const result = await User.aggregate([
  { $match: { age: { $gte: 21 } } },
  { $group: {
    _id: '$name',
    total: { $sum: 1 }
  }}
]);

Performance Optimization

  1. Index Optimization:
userSchema.index({ name: 1, age: -1 });
  1. Query Selectivity:
// Avoid full table scans
User.find().where('age').gt(20).select('name');
  1. Bulk Operations:
// Bulk inserts are 10x faster than looping single inserts
User.insertMany([
  { name: 'User1' },
  { name: 'User2' }
]);

Practical Application Scenarios

User Management System

Complete user management module example:

// Controller methods
class UserController {
  async list(ctx) {
    const { page = 1, size = 10 } = ctx.query;
    const users = await User.find()
      .skip((page - 1) * size)
      .limit(Number(size));
    ctx.body = users;
  }

  async create(ctx) {
    const user = new User(ctx.request.body);
    await user.save();
    ctx.status = 201;
  }
}

// Route configuration
router.get('/users', UserController.list);
router.post('/users', UserController.create);

Real-time Data Statistics

Real-time reporting system with WebSocket:

const changeStream = User.watch();
changeStream.on('change', (change) => {
  io.emit('user_change', change);
});

Error Handling and Debugging

Common Error Types

  1. Connection Errors:
mongoose.connection.on('error', err => {
  console.error('DB connection error:', err);
});
  1. Validation Errors:
try {
  await user.save();
} catch (err) {
  if (err.name === 'ValidationError') {
    console.log(err.errors);
  }
}

Debugging Tips

Enable query logging:

mongoose.set('debug', true);

Performance profiling:

const start = Date.now();
await User.find().explain('executionStats');
console.log(`Query took ${Date.now() - start}ms`);

Extensions and Integrations

Multiple Database Connections

Connect to multiple MongoDB instances simultaneously:

const conn1 = mongoose.createConnection('mongodb://localhost/db1');
const conn2 = mongoose.createConnection('mongodb://localhost/db2');

Integration with GraphQL

Create GraphQL resolvers:

const resolvers = {
  Query: {
    users: async () => await User.find()
  },
  Mutation: {
    createUser: async (_, { input }) => {
      return await User.create(input);
    }
  }
};

TypeScript Support

Define Mongoose model interfaces:

interface IUser extends mongoose.Document {
  name: string;
  age?: number;
}

const User = mongoose.model<IUser>('User', userSchema);

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.