Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

ทำ Alphanumeric Sort (เรียงตัวเลขในสตริง) ใน MongoDB

ใช้ 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คำอธิบาย
localeLocale สำหรับกฎการเรียง (เช่น "en_US", "th", "zh")
numericOrderingtrue/false - เรียงตัวเลขในสตริงเป็นจำนวน
caseLeveltrue/false - แยกพิมพ์ใหญ่/เล็ก
caseFirst"upper" / "lower" / "off" - ใครอยู่หน้า
strength1-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 ทำงานเหมือนกัน)