ใช้ Collation numericOrdering: true เรียงสตริงที่มีตัวเลขให้ถูกต้อง
Default Sort ของ MongoDB เรียงแบบ Lexicographic (ตัวอักษร) ทำให้ "STU1010" อยู่ก่อน "STU908" แต่ถ้าเปิด numericOrdering จะอ่านตัวเลขในสตริงเป็นจำนวน
ตัวอย่างข้อมูล
> db.alphanumericSortDemo.insertOne({"StudentId":"STU1010"});
> db.alphanumericSortDemo.insertOne({"StudentId":"STU1101"});
> db.alphanumericSortDemo.insertOne({"StudentId":"STU1901"});
> db.alphanumericSortDemo.insertOne({"StudentId":"STU908"});
> db.alphanumericSortDemo.insertOne({"StudentId":"STU101"});
Case 1: Ascending (น้อยไปมาก) พร้อม Numeric Ordering
> db.alphanumericSortDemo.find({}).sort({ "StudentId": 1 }).collation({ locale: "en_US", numericOrdering: true });
ผลลัพธ์: STU101, STU908, STU1010, STU1101, STU1901 ✅
Case 2: Descending (มากไปน้อย) พร้อม Numeric Ordering
> db.alphanumericSortDemo.find({}).sort({ "StudentId": -1 }).collation({ locale: "en_US", numericOrdering: true });
ผลลัพธ์: STU1901, STU1101, STU1010, STU908, STU101 ✅
เปรียบเทียบ: ไม่ใช้ Numeric Ordering (Default)
> db.alphanumericSortDemo.find({}).sort({ "StudentId": 1 });
// ผลลัพธ์: STU101, STU1010, STU1101, STU1901, STU908 ❌ ผิด (Lexicographic)
Collation Options
| Option | คำอธิบาย |
|---|---|
locale | Locale สำหรับกฎการเรียง (เช่น "en_US", "th", "zh") |
numericOrdering | true/false - เรียงตัวเลขในสตริงเป็นจำนวน |
caseLevel | true/false - แยกพิมพ์ใหญ่/เล็ก |
caseFirst | "upper" / "lower" / "off" - ใครอยู่หน้า |
strength | 1-5 - ระดับความละเอียด (1=base char only, 5=identical) |
การใช้งานกับ Index
// สร้าง Index พร้อม Collation
db.alphanumericSortDemo.createIndex(
{ StudentId: 1 },
{ collation: { locale: "en_US", numericOrdering: true } }
);
// Query ต้องระบุ Collation เดียวกัน
db.alphanumericSortDemo.find().sort({ StudentId: 1 }).collation({ locale: "en_US", numericOrdering: true });
สรุป
- ใช้
.collation({ locale: "en_US", numericOrdering: true })สำหรับ Alphanumeric Sort - ต้องระบุ Collation ตรงกันระหว่าง Index และ Query
- รองรับใน find(), sort(), aggregate(), createIndex()
- Locale "en_US" ใช้ได้ทั่วไป สำหรับไทยใช้ "th" (แต่ numericOrdering ทำงานเหมือนกัน)