CRUD Cơ Bản
Chèn
db.users.insertOne({ name: "Alice", age: 30 }); db.users.insertMany([ { name: "Bob", age: 25 }, { name: "Carol", age: 35 } ]);
Tìm Kiếm
db.users.find({}); // all documents db.users.findOne({ name: "Alice" }); db.users.find({ age: { $gt: 25 } }); db.users.find({}, { name: 1, _id: 0 }); // projection
Cập Nhật
db.users.updateOne( { name: "Alice" }, { $set: { age: 31 } } ); db.users.updateMany( { age: { $lt: 18 } }, { $set: { minor: true } } ); db.users.replaceOne({ name: "Bob" }, { name: "Bob", age: 26 });
Xóa
db.users.deleteOne({ name: "Alice" }); db.users.deleteMany({ age: { $lt: 18 } });
Toán Tử Truy Vấn
So Sánh
$eq / $neBằng / không bằng
$gt / $gteLớn hơn / lớn hơn hoặc bằng
$lt / $lteNhỏ hơn / nhỏ hơn hoặc bằng
$in / $ninThuộc / không thuộc tập hợp
$existsField tồn tại hay không
$typeKiểm tra kiểu BSON
Logic
$andTất cả điều kiện phải đúng
$orÍt nhất một điều kiện đúng
$notPhủ định biểu thức
$norKhông điều kiện nào đúng
Mảng & Element
$allMảng chứa tất cả giá trị
$elemMatchPhần tử trong mảng thỏa tất cả điều kiện
$sizeMảng có kích thước cụ thể
$regexKhớp biểu thức chính quy
Truy Vấn Ví Dụ
db.products.find({ price: { $gte: 10, $lte: 100 }, tags: { $in: ["sale", "featured"] }, "address.city": "NYC" });
Toán Tử Cập Nhật
Cập Nhật Field
$setĐặt giá trị field
$unsetXóa field
$incTăng giá trị số
$mulNhân giá trị số
$renameĐổi tên field
$currentDateĐặt field thành ngày hiện tại
$setOnInsertChỉ đặt khi upsert tạo document mới
Cập Nhật Mảng
$pushThêm phần tử vào mảng
$pullXóa phần tử khỏi mảng
$addToSetThêm nếu chưa có
$popXóa phần tử đầu (-1) hoặc cuối (1)
$eachDùng với $push để thêm nhiều phần tử
Upsert
db.users.updateOne( { email: "[email protected]" }, { $set: { name: "Alice" }, $setOnInsert: { createdAt: new Date() } }, { upsert: true } );
Aggregation Pipeline
Các Stages Phổ Biến
$matchLọc documents (như WHERE)
$groupNhóm và tính tổng hợp
$projectHình thành lại documents (chọn/đổi tên fields)
$sortSắp xếp documents
$limit / $skipPhân trang
$unwindPhân rã mảng thành nhiều documents
$lookupJoin với collection khác
$addFieldsThêm fields mới vào documents
$countĐếm tổng số documents
Ví Dụ Aggregation
db.orders.aggregate([ { $match: { status: "completed" } }, { $group: { _id: "$customerId", total: { $sum: "$amount" }, count: { $sum: 1 } }}, { $sort: { total: -1 } }, { $limit: 10 } ]);
Lookup (Join)
db.orders.aggregate([ { $lookup: { from: "customers", localField: "customerId", foreignField: "_id", as: "customer" }}, { $unwind: "$customer" } ]);
Indexes
Tạo Indexes
db.users.createIndex({ email: 1 }); // ascending db.users.createIndex({ age: -1 }); // descending db.users.createIndex({ email: 1 }, { unique: true }); db.users.createIndex({ name: "text" }); // text search db.places.createIndex({ location: "2dsphere" });
Quản Lý Index
db.users.getIndexes(); db.users.dropIndex("email_1"); db.users.explain("executionStats").find({ email: "..." });
Loại Index
Single fieldMột trường, tăng/giảm dần
CompoundNhiều trường (thứ tự quan trọng)
MultikeyIndex trên trường mảng
TextTìm kiếm văn bản toàn văn
GeospatialTruy vấn dữ liệu địa lý
HashedDùng cho sharding
Thiết Kế Schema
Nhúng vs Tham Chiếu
Nhúng (Embedding)Dùng khi dữ liệu luôn được đọc cùng nhau
Tham chiếu (Reference)Dùng khi dữ liệu lớn hoặc được chia sẻ
Mảng nhúngTốt cho danh sách nhỏ, ổn định
$lookupJoin tại query-time (hiệu suất thấp hơn)
Mẫu Phổ Biến
// Embedded (one-to-few) { name: "Alice", address: { city: "NYC" } } // Referenced (one-to-many) { _id: OrderId, userId: ObjectId("...") } // Bucket pattern (time-series) { sensor: "t1", date: ISODate("2024-01-01"), readings: [{ t: ..., v: ... }] }
Mẫu Phổ Biến
Phân Trang
const page = 2, limit = 10; db.posts.find({}) .sort({ createdAt: -1 }) .skip((page - 1) * limit) .limit(limit);
Tìm Kiếm Văn Bản
db.articles.createIndex({ title: "text", body: "text" }); db.articles.find({ $text: { $search: "mongodb query" } }, { score: { $meta: "textScore" } }) .sort({ score: { $meta: "textScore" } });
Thống Kê & Thông Tin
db.users.countDocuments({ active: true }); db.users.estimatedDocumentCount(); db.stats(); db.users.stats();