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

Thêm timestamp chỉ khi chưa có trong MongoDB (upsert + multi)

Cập nhật trường DueDate chỉ khi chưa tồn tại (conditional update)

Kết hợp $exists: false trong filter với multi: true (updateMany) để set timestamp cho tất cả document thiếu trường đó.

1. Dữ liệu: Có document đã có DueDate, có document chưa có

> db.demo479.insertOne({ DueDate: new ISODate("2020-01-10"), Name: "Chris" });
> db.demo479.insertOne({ Name: "David" });  // Thiếu DueDate
> db.demo479.insertOne({ DueDate: new ISODate("2019-12-31"), Name: "Bob" });
> db.demo479.insertOne({ Name: "Carol" });  // Thiếu DueDate

2. Cập nhật: Set DueDate = now() cho doc CHƯA CÓ DueDate

> db.demo479.update(
    { DueDate: { $exists: false } },      // Filter: thiếu DueDate
    { $set: { "DueDate": new Date } },    // Set giờ hiện tại
    { upsert: false, multi: true }        // multi=true = updateMany
);
WriteResult({ "nMatched": 2, "nUpserted": 0, "nModified": 2 })

3. Kết quả

> db.demo479.find();
{ "_id": ObjectId("5e820733b0f3fa88e2279094"), "DueDate": ISODate("2020-01-10T00:00:00Z"), "Name": "Chris" }
{ "_id": ObjectId("5e820748b0f3fa88e2279095"), "Name": "David", "DueDate": ISODate("2020-03-30T14:52:29.656Z") }  // Mới thêm
{ "_id": ObjectId("5e82075fb0f3fa88e2279096"), "DueDate": ISODate("2019-12-31T00:00:00Z"), "Name": "Bob" }
{ "_id": ObjectId("5e820767b0f3fa88e2279097"), "Name": "Carol", "DueDate": ISODate("2020-03-30T14:52:29.656Z") }  // Mới thêm

Giải thích tham số

Tham sốGiá trịÝ nghĩa
upsertfalseKhông tạo document mới nếu không match
multitrueCập nhật TẤT CẢ document khớp (mặc định false = chỉ 1)

Phiên bản hiện đại (MongoDB 3.2+)

db.demo479.updateMany(
    { DueDate: { $exists: false } },
    { $set: { DueDate: new Date() } }
    // Không cần upsert/multi - updateMany đã xử lý multi
);

Mở rộng: Conditional update với $setOnInsert (chỉ khi upsert)

// Chỉ set createdAt khi INSERT MỚI (upsert=true)
db.demo479.updateOne(
    { _id: someId },
    { 
        $set: { updatedAt: new Date() },
        $setOnInsert: { createdAt: new Date() }  // Chỉ chạy khi insert mới
    },
    { upsert: true }
);

Ứng dụng thực tế

  • Backfill dữ liệu: Thêm trường mới cho document cũ
  • Migration schema: Set default value cho field mới
  • Timestamp tự động: createdAt (chỉ insert), updatedAt (mỗi update)