ObjectId ใน MongoDB ไม่รับ seed string ได้ (ไม่สามารถสร้าง ObjectId จากสตริงที่กำลังใจได้) วิธีแก้คือใช้ _id เป็น String เอง
> db.demo667.insertOne({_id: "Chris"});
{ "acknowledged" : true, "insertedId" : "Chris" }
> db.demo667.insertOne({_id: "David"});
{ "acknowledged" : true, "insertedId" : "David" }
> db.demo667.insertOne({_id: "Chris" });
2020-04-23T22:01:23.268+0530 E QUERY [js] WriteError: E11000 duplicate key error collection: test.demo667 index: _id_ dup key: { : "Chris" }
> db.demo667.insertOne({_id: "Bob"});
{ "acknowledged" : true, "insertedId" : "Bob" }
> db.demo667.insertOne({_id: "Mike"});
{ "acknowledged" : true, "insertedId" : "Mike" }
แสดงข้อมูล:
> db.demo667.find();
ข้อเท็จจริงเกี่ยวกับ ObjectId
- ObjectId เป็น 12-byte BSON type: 4-byte timestamp + 5-byte random + 3-byte counter
- สร้างอัตโนมัติโดย driver/server ไม่รับค่า seed จากผู้ใช้
- Unique แทบแน่นอน (collision probability 極低)
- เรียงตามเวลาได้ (timestamp อยู่ใน 4 byte แรก)
เมื่อไหร่ควรใช้ Custom _id (String)
- มี Natural Key แล้ว (username, email, ISBN, SKU)
- ต้องการ _id ที่อ่านง่าย / ใช้ใน URL ได้
- Migrate จากระบบเก่าที่มี ID อยู่แล้ว
ข้อดี/เสีย Custom _id
| ข้อดี | ข้อเสีย |
|---|---|
| อ่านง่าย, meaningful | ไม่มี timestamp built-in |
| ควบคุม format เอง | ต้อง ensure uniqueness เอง |
| เหมาะ sharding key | อาจกระจายข้อมูลไม่勻 (hotspot) |