Khắc phục lỗi MongoDB: Cannot create field in element {field: null}

intermediate🍃 MongoDB2026-06-09| MongoDB (Mọi phiên bản), Node.js/Python/Go Drivers, MongoDB Atlas

Error Message

MongoServerError: Cannot create field 'city' in element {address: null}
#mongodb#nosql#loi-co-so-du-lieu#phat-trien-backend#truy-van-mongodb

Cách khắc phục nhanh

Lỗi này xảy ra khi bạn cố gắng cập nhật một trường lồng nhau—ví dụ address.city—nhưng trường cha (address) đang được đặt là null một cách rõ ràng trong cơ sở dữ liệu. MongoDB không thể tự động chuyển đổi một giá trị null thành một đối tượng (object).

Cách nhanh nhất để khắc phục là ghi đè toàn bộ đối tượng cha. Hãy sử dụng cách này nếu bạn không ngại thay thế bất kỳ dữ liệu nào đang có trong trường đó:

db.users.updateOne(
  { _id: ObjectId("64f1a2b3c4d5e6f7a8b9c0d1") },
  { $set: { "address": { "city": "New York" } } }
)

Nếu bạn cần giữ lại các dữ liệu khác bên trong address, bạn sẽ cần một phương pháp cụ thể hơn. Hãy cùng tìm hiểu lý do tại sao lỗi này xảy ra và cách xử lý an toàn.

Tại sao lỗi này xảy ra?

Dot notation của MongoDB rất mạnh mẽ nhưng cũng rất khắt khe. Nó chỉ có thể điều hướng qua các đối tượng (objects). Nó không thể truy cập sâu vào null, chuỗi (strings) hoặc kiểu boolean.

Giả sử tài liệu của bạn trông như thế này:

{
  "_id": 101,
  "name": "Alice Smith",
  "address": null
}

Khi bạn chạy lệnh { $set: { "address.city": "Seattle" } }, MongoDB kiểm tra address và gặp ngõ cụt. Vì null là một giá trị nguyên thủy (primitive value), MongoDB không biết cách gắn một thuộc tính con vào nó. Nó sẽ dừng lại ngay lập tức và báo lỗi MongoServerError.

Thật thú vị là nếu trường address hoàn toàn không tồn tại, MongoDB sẽ tự động xây dựng cấu trúc đối tượng cho bạn. Lỗi này chỉ xảy ra vì trường đó đã tồn tại nhưng sai kiểu dữ liệu.

3 cách để khắc phục

1. Ghi đè trường cha (Cách trực tiếp)

Sử dụng cách này nếu trường đó chắc chắn là null hoặc nếu bạn muốn đặt lại đối tượng. Đây là phương pháp hiệu quả nhất về hiệu năng vì không yêu cầu logic phức tạp.

// Lệnh này thay thế null bằng một đối tượng mới
db.collection.updateOne(
  { _id: 101 },
  { $set: { address: { city: "Austin" } } }
)

2. Làm sạch dữ liệu trước (Tốt nhất cho sửa lỗi hàng loạt)

Đôi khi bạn có hàng ngàn tài liệu chứa giá trị null. Bạn có thể chạy một script dọn dẹp nhanh để chuyển tất cả address đang là null thành các đối tượng rỗng. Khi chúng đã là đối tượng, các lệnh cập nhật dot notation tiêu chuẩn sẽ hoạt động hoàn hảo.

// Bước 1: Chuyển đổi null thành đối tượng rỗng
db.collection.updateMany(
  { address: null },
  { $set: { address: {} } }
);

// Bước 2: Bây giờ lệnh cập nhật thông thường sẽ hoạt động
db.collection.updateOne(
  { _id: 101 },
  { $set: { "address.city": "Austin" } }
);

3. Cập nhật thông minh (MongoDB 4.2+)

Các phiên bản MongoDB hiện đại hỗ trợ aggregation pipeline bên trong lệnh update. Đây là phương pháp mạnh mẽ nhất. Nó kiểm tra kiểu dữ liệu ngay lập tức và quyết định nên gộp (merge) hay thay thế.

db.collection.updateOne(
  { _id: 101 },
  [
    {
      $set: {
        address: {
          $cond: {
            if: { $eq: [{ $type: "$address" }, "object"] },
            then: { $mergeObjects: ["$address", { city: "Austin" }] },
            else: { city: "Austin" }
          }
        }
      }
    }
  ]
)

Script này sẽ kiểm tra: "Trường address đã là một đối tượng chưa?" Nếu đúng, nó sẽ gộp thành phố mới vào dữ liệu hiện có. Nếu không (đang là null hoặc một chuỗi), nó sẽ tạo ra một đối tượng hoàn toàn mới.

Cách kiểm tra thay đổi

Kiểm tra kết quả bằng cách truy vấn trực tiếp tài liệu. Chạy lệnh này trong shell của bạn:

db.collection.find({ _id: 101 }).pretty()

Bạn sẽ thấy một cấu trúc lồng nhau sạch sẽ như thế này:

{
  "_id": 101,
  "address": {
    "city": "Austin"
  }
}

Thói quen thiết kế Schema tốt hơn

Bạn có thể tránh hoàn toàn rắc rối này bằng một thay đổi nhỏ trong thiết kế schema. Đừng khởi tạo các đối tượng lồng nhau là null. Nếu người dùng chưa cung cấp địa chỉ, chỉ cần bỏ qua trường address khỏi tài liệu. MongoDB xử lý các trường bị thiếu tốt hơn nhiều so với các trường có giá trị null rõ ràng khi thực hiện cập nhật.

Related Error Notes