MongoDB integration and ORM usage
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
- Index Optimization:
userSchema.index({ name: 1, age: -1 });
- Query Selectivity:
// Avoid full table scans
User.find().where('age').gt(20).select('name');
- 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
- Connection Errors:
mongoose.connection.on('error', err => {
console.error('DB connection error:', err);
});
- 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
上一篇:MySQL 数据库连接与操作
下一篇:Redis 缓存集成方案