แปลง String เป็น ObjectId ด้วย Aggregation
เมื่อ _id เก็บเป็น String แต่ต้องการใช้เป็น ObjectId ให้ใช้ aggregation pipeline พร้อม $toObjectId (MongoDB 4.0+) หรือ $convert
ตัวอย่างข้อมูล _id เป็น String
> db.demo460.insertOne({ "_id": "5ab9cbfa31c2ab715d42129e" });
{ "acknowledged": true, "insertedId": "5ab9cbfa31c2ab715d42129e" }
Query แปลงเป็น ObjectId (MongoDB 4.0+)
> db.demo460.aggregate([
{ $addFields: { value: { $toObjectId: "$_id" } } }
]);
ผลลัพธ์
{ "_id": "5ab9cbfa31c2ab715d42129e", "value": ObjectId("5ab9cbfa31c2ab715d42129e") }
รุ่นเก่า ใช้ $convert
db.demo460.aggregate([
{ $addFields: { value: { $convert: { input: "$_id", to: "objectId" } } } }
]);
สาเหตุทั่วไปของ Error "Cast to ObjectId failed"
- String ไม่ใช่รูปแบบ ObjectId ที่ถูกต้อง (ต้อง 24 hex characters)
- พยายาม query ด้วย string แทน ObjectId:
find({ _id: "507f1f77bcf86cd799439011" })แทนfind({ _id: ObjectId("507f1f77bcf86cd799439011") }) - Driver ไม่ได้แปลงอัตโนมัติ (บาง driver ต้องแปลงเอง)
แนวทางปฏิบัติที่ดี
- ให้ _id เป็น ObjectId ตั้งแต่แรก (default behavior)
- หากต้องเก็บ string ให้ใช้ฟิลด์อื่น เช่น "externalId"
- ใช้ $toObjectId ใน aggregation เพื่อแปลงระหว่าง query