Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Cách dùng save() đúng trong MongoDB

Phương thức save(): Upsert tự động (insert hoặc update)

db.collection.save(doc) tự động quyết định: nếu doc có _id → update (replace), nếu không có _id → insert mới.

1. Ví dụ: Insert 4 document (không có _id)

> db.demo481.save({ "FirstName": "Chris", "LastName": "Brown" });
WriteResult({ "nInserted": 1 })

> db.demo481.save({ "FirstName": "David", "LastName": "Miller" });
WriteResult({ "nInserted": 1 })

> db.demo481.save({ "FirstName": "John", "LastName": "Doe" });
WriteResult({ "nInserted": 1 })

> db.demo481.save({ "FirstName": "John", "LastName": "Smith" });
WriteResult({ "nInserted": 1 })

2. Kết quả: 4 document với _id tự động

> db.demo481.find();
{ "_id": ObjectId("5e82db39b0f3fa88e227909c"), "FirstName": "Chris", "LastName": "Brown" }
{ "_id": ObjectId("5e82db45b0f3fa88e227909d"), "FirstName": "David", "LastName": "Miller" }
{ "_id": ObjectId("5e82db4db0f3fa88e227909e"), "FirstName": "John", "LastName": "Doe" }
{ "_id": ObjectId("5e82db52b0f3fa88e227909f"), "FirstName": "John", "LastName": "Smith" }

3. Cập nhật: Gọi save() với _id đã có

> var doc = db.demo481.findOne({ FirstName: "Chris" });
> doc.LastName = "White";
> db.demo481.save(doc);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })

⚠️ save() ĐÃ DEPRECATED (MongoDB 4.2+)

Phương thức cũThay thế hiện đạiLưu ý
save(doc)insertOne(doc) / replaceOne({_id}, doc)Tách biệt rõ ràng insert vs replace
update()updateOne() / updateMany()Rõ ràng số lượng doc ảnh hưởng
remove()deleteOne() / deleteMany()Rõ ràng số lượng doc xóa

Tại sao save() không khuyến khích?

  • Nhầm lẫn giữa insert và replace (gây bug: vô tình tạo doc mới khi _id sai)
  • replaceOne thay thế TOÀN BỘ doc (kể cả trường không gửi) → mất data nếu không cẩn thận
  • Không hỗ trợ atomic operators ($set, $inc, $push...)
  • Không trả về chi tiết kết quả như write concern

Best Practice hiện nay

// INSERT mới (tự động gen _id)
db.collection.insertOne({ name: "New" });

// UPDATE một phần (an toàn, giữ trường khác)
db.collection.updateOne(
    { _id: existingId },
    { $set: { name: "Updated" } }
);

// REPLACE toàn bộ (nếu thực sự muốn)
db.collection.replaceOne(
    { _id: existingId },
    { name: "New Name", otherField: "value" }
);

Tóm lại: Chỉ dùng save() trong shell ad-hoc, KHÔNG dùng trong production code.