ใช้ Compound Unique Index เพื่อบังคับให้ชุดค่าของ 2 ฟิลด์ (หรือมากกว่า) ไม่ซ้ำกันในคอลเลกชัน (Composite Unique Constraint)
สร้าง Compound Unique Index
> db.keepTwoColumnsUniqueDemo.createIndex(
{"StudentFirstName": 1, "StudentLastName": 1},
{unique: true}
);
{
"createdCollectionAutomatically": true,
"numIndexesBefore": 1,
"numIndexesAfter": 2,
"ok": 1
}
ทดสอบ Insert ข้อมูล
> db.keepTwoColumnsUniqueDemo.insertOne({"StudentFirstName":"John","StudentLastName":"Smith","StudentAge":21});
{ "acknowledged": true, "insertedId": ObjectId("5cd30fd7b64f4b851c3a13e5") }
> db.keepTwoColumnsUniqueDemo.insertOne({"StudentFirstName":"John","StudentLastName":"Doe","StudentAge":23});
{ "acknowledged": true, "insertedId": ObjectId("5cd30fe5b64f4b851c3a13e6") }
> db.keepTwoColumnsUniqueDemo.insertOne({"StudentFirstName":"John","StudentLastName":"Smith","StudentAge":24});
// ERROR: Duplicate key
2019-05-08T22:50:42.803+0530 E QUERY [js] WriteError: E11000 duplicate key error collection: sample.keepTwoColumnsUniqueDemo index: StudentFirstName_1_StudentLastName_1 dup key: { : "John", : "Smith" }
Error: E11000 duplicate key error เพราะ (John, Smith) มีอยู่แล้ว
แสดงข้อมูลที่ Insert สำเร็จ
> db.keepTwoColumnsUniqueDemo.find().pretty();
ผลลัพธ์ (2 เอกสาร):
{
"_id": ObjectId("5cd30fd7b64f4b851c3a13e5"),
"StudentFirstName": "John",
"StudentLastName": "Smith",
"StudentAge": 21
}
{
"_id": ObjectId("5cd30fe5b64f4b851c3a13e6"),
"StudentFirstName": "John",
"StudentLastName": "Doe",
"StudentAge": 23
}
รายละเอียด Compound Unique Index
- Syntax:
db.coll.createIndex({field1: 1, field2: 1}, {unique: true}) - บังคับให้ ชุดค่า (field1, field2) ไม่ซ้ำกัน
- ฟิลด์เดี่ยวอาจซ้ำได้ (John ปรากฏ 2 ครั้ง) แต่คู่ (John, Smith) ต้อง Unique
- ลำดับฟิลด์ใน Index สำคัญต่อ Query Performance (ESR Rule)
- Index Name อัตโนมัติ:
StudentFirstName_1_StudentLastName_1
กรณีใช้งานจริง
- User: (email, provider) - อนุญาต email เดียวกันได้ถ้า Provider ต่างกัน (Google, Facebook)
- Order Item: (orderId, productId) - ห้ามซ้ำสินค้าใน Order เดียวกัน
- Enrollment: (studentId, courseId) - นักเรียนลงทะเบียนคอร์สเดียวกันได้ครั้งเดียว
คำสั่งที่เกี่ยวข้อง
// ดู Indexes
db.keepTwoColumnsUniqueDemo.getIndexes();
// ลบ Index
db.keepTwoColumnsUniqueDemo.dropIndex("StudentFirstName_1_StudentLastName_1");
// Unique Index บนฟิลด์เดียว
db.users.createIndex({"email": 1}, {unique: true});