So sánh chuỗi không phân biệt chữ hoa/thường: $strcasecmp
Toán tử $strcasecmp trong aggregation so sánh 2 chuỗi case-insensitive, trả về -1, 0, 1.
1. Dữ liệu mẫu
> db.demo490.insertOne({ Name1: "John", Name2: "john" });
> db.demo490.insertOne({ Name1: "David", Name2: "Bob" });
> db.demo490.insertOne({ Name1: "Carol", Name2: "Carol" });
2. Pipeline so sánh
> db.demo490.aggregate([
{
$project: {
Name1: 1,
Name2: 1,
Result: { $strcasecmp: ["$Name1", "$Name2"] }
}
}
]);
3. Kết quả
{ "_id": ObjectId("5e8496ccb0f3fa88e22790bb"), "Name1": "John", "Name2": "john", "Result": 0 }
{ "_id": ObjectId("5e8496d9b0f3fa88e22790bc"), "Name1": "David", "Name2": "Bob", "Result": 1 }
{ "_id": ObjectId("5e8496e5b0f3fa88e22790bd"), "Name1": "Carol", "Name2": "Carol", "Result": 0 }
Giải thích kết quả
| Kết quả | Ý nghĩa | Ví dụ |
| 0 | Hai chuỗi bằng nhau (ignore case) | "John" vs "john" → 0 |
| 1 | Chuỗi 1 > Chuỗi 2 (lexicographic) | "David" > "Bob" → 1 |
| -1 | Chuỗi 1 < Chuỗi 2 | "Bob" < "David" → -1 |
So sánh với các phương pháp khác
| Phương pháp | Case-sensitive | Trả về | Dùng trong |
| $strcasecmp | ❌ Không | -1, 0, 1 | Aggregation |
| $cmp | ✅ Có | -1, 0, 1 | Aggregation |
| $eq | ✅ Có | true/false | Find, Aggregation |
| $regex + 'i' | ❌ Không | true/false | Find, Aggregation |
Ứng dụng thực tế
// 1. Sắp xếp case-insensitive
db.collection.aggregate([
{ $project: { name: 1, lowerName: { $toLower: "$name" } } },
{ $sort: { lowerName: 1 } }
]);
// 2. Group case-insensitive (gộp "John", "john", "JOHN")
db.collection.aggregate([
{ $group: { _id: { $toLower: "$name" }, count: { $sum: 1 } } }
]);
// 3. $strcasecmp trong $match (filter)
db.collection.aggregate([
{ $match: { $expr: { $eq: [{ $strcasecmp: ["$name", "john"] }, 0] } } }
]);
Lưu ý Unicode
$strcasecmp dùng so sánh byte-level (ASCII)
- Với Unicode (tiếng Việt, tiếng Nhật...): Kết quả có thể không đúng chuẩn locale
- Giải pháp: Chuẩn hóa về lowercase ở application layer, hoặc dùng Collation (MongoDB 3.4+)
Collation (MongoDB 3.4+) - Chuẩn hơn cho Unicode
// Tìm case-insensitive với collation tiếng Việt
db.collection.find(
{ name: "nguyễn văn a" },
{ collation: { locale: "vi", strength: 2 } } // strength 2 = case-insensitive
);
// Sort với collation
db.collection.find().collation({ locale: "vi" }).sort({ name: 1 });