เรียงลำดับเอกสารตามลำดับความสำคัญของคำเฉพาะ (Custom Sort Order)
เมื่อต้องการเรียงลำดับเอกสารตามค่าข้อความที่ไม่ใช่เรียงอักษรปกติ (เช่น เรียง MongoDB ก่อน MySQL ก่อน Java) ให้สร้างฟิลด์ช่วยสำหรับการเรียงด้วย $addFields และ $cond แล้วค่อย $sort
ตัวอย่างข้อมูลทดสอบ
> db.demo62.insertOne({ "Subject": "MySQL" });
> db.demo62.insertOne({ "Subject": "MongoDB" });
> db.demo62.insertOne({ "Subject": "Java" });
แสดงข้อมูลก่อนเรียง
> db.demo62.find();
ผลลัพธ์ (เรียงตาม _id):
{ "_id": ObjectId("..."), "Subject": "MySQL" }
{ "_id": ObjectId("..."), "Subject": "MongoDB" }
{ "_id": ObjectId("..."), "Subject": "Java" }
คำสั่ง Aggregation เรียงตามลำดับที่กำหนดเอง
> db.demo62.aggregate([
{
$addFields: {
sortByWords: {
$cond: [
{ $eq: ["$Subject", "MongoDB"] }, 0,
{ $cond: [{ $eq: ["$Subject", "MySQL"] }, 1, 2] }
]
}
}
},
{ $sort: { sortByWords: 1 } }
]);
ผลลัพธ์ที่ได้
{ "_id": ObjectId("..."), "Subject": "MongoDB", "sortByWords": 0 }
{ "_id": ObjectId("..."), "Subject": "MySQL", "sortByWords": 1 }
{ "_id": ObjectId("..."), "Subject": "Java", "sortByWords": 2 }
คำอธิบาย
- $addFields: เพิ่มฟิลด์ sortByWords คำนวณจาก Subject
- $cond แบบ nested: ถ้า Subject="MongoDB" ให้ 0, ถ้า="MySQL" ให้ 1, อื่นๆ ให้ 2
- $sort: { sortByWords: 1 }: เรียงตามฟิลด์ช่วยจากน้อยไปมาก
วิธีที่ง่ายกว่า (MongoDB 3.6+): ใช้ $switch
> db.demo62.aggregate([
{
$addFields: {
sortByWords: {
$switch: {
branches: [
{ case: { $eq: ["$Subject", "MongoDB"] }, then: 0 },
{ case: { $eq: ["$Subject", "MySQL"] }, then: 1 }
],
default: 2
}
}
}
},
{ $sort: { sortByWords: 1 } }
]);
$switch อ่านง่ายกว่า $cond แบบ nested มาก