MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Mongoose ghi đè lên tài liệu thay vì các trường `$ set`

Trên thực tế, nhưng thực tế là mongoose đang thực sự "gây rối" với bản cập nhật dưới vỏ bọc, đây thực sự là hành động mặc định khi bạn gửi một hàm MongoDB thông thường.

Vì vậy mongoose cho rằng nó "khôn ngoan" như một phương pháp tiện lợi để "đoán trước" bạn định phát hành $set hướng dẫn ở đây. Vì bạn thực sự không muốn làm điều đó trong trường hợp này, bạn tắt hành vi đó thông qua { overwrite: true } trong các tùy chọn được chuyển đến bất kỳ .update() nào phương pháp:

Như một ví dụ đầy đủ:

const mongoose = require('mongoose'),
      Schema = mongoose.Schema;

mongoose.Promise = global.Promise;
mongoose.set('debug',true);

const uri = 'mongodb://localhost/test',
      options = { useMongoClient: true };

const testSchema = new Schema({
  name: String,
  phone: String
});

const Test = mongoose.model('Test', testSchema);

function log(data) {
  console.log(JSON.stringify(data,undefined,2))
}

(async function() {

  try {

    const conn = await mongoose.connect(uri,options);

    // Clean data
    await Promise.all(
      Object.keys(conn.models).map( m => conn.models[m].remove({}) )
    );

    // Create a document
    let test = await Test.create({
      name: 'john doe',
      phone: '+12345678901'
    });
    log(test);

    // This update will apply using $set for the name
    let notover = await Test.findOneAndUpdate(
      { _id: test._id },
      { name: 'Bill S. Preston' },
      { new: true }
    );
    log(notover);

    // This update will just use the supplied object, and overwrite
    let updated = await Test.findOneAndUpdate(
      { _id: test._id },
      { name: 'Dan Smith' },
      { new: true, overwrite: true }
    );
    log(updated);


  } catch (e) {
    console.error(e);
  } finally {
    mongoose.disconnect();
  }

})()

Sản xuất:

Mongoose: tests.remove({}, {})
Mongoose: tests.insert({ name: 'john doe', phone: '+12345678901', _id: ObjectId("596efb0ec941ff0ec319ac1e"), __v: 0 })
{
  "__v": 0,
  "name": "john doe",
  "phone": "+12345678901",
  "_id": "596efb0ec941ff0ec319ac1e"
}
Mongoose: tests.findAndModify({ _id: ObjectId("596efb0ec941ff0ec319ac1e") }, [], { '$set': { name: 'Bill S. Preston' } }, { new: true, upsert: false, remove: false, fields: {} })
{
  "_id": "596efb0ec941ff0ec319ac1e",
  "name": "Bill S. Preston",
  "phone": "+12345678901",
  "__v": 0
}
Mongoose: tests.findAndModify({ _id: ObjectId("596efb0ec941ff0ec319ac1e") }, [], { name: 'Dan Smith' }, { new: true, overwrite: true, upsert: false, remove: false, fields: {} })
{
  "_id": "596efb0ec941ff0ec319ac1e",
  "name": "Dan Smith"
}

Việc hiển thị tài liệu bị "ghi đè" vì chúng tôi đã chặn $set hoạt động mà nếu không sẽ được nội suy. Hai mẫu hiển thị đầu tiên mà không có overwrite , áp dụng $set sửa đổi, và sau đó "với" overwrite tùy chọn, trong đó đối tượng bạn đã chuyển vào cho "bản cập nhật" được tôn trọng và không có $set nào như vậy công cụ sửa đổi được áp dụng.

Lưu ý, đây là cách trình điều khiển MongoDB Node thực hiện điều này "theo mặc định". Vì vậy, hành vi thêm vào $set "ngầm định" đang được thực hiện bởi mongoose, trừ khi bạn yêu cầu nó không làm như vậy.

LƯU Ý Cách thực sự để "thay thế" thực sự sẽ là sử dụng replaceOne , hoặc là phương thức API của replaceOne() hoặc thông qua bulkWrite() . overwrite là di sản của cách mongoose muốn áp dụng $set như được mô tả và trình bày ở trên, tuy nhiên API chính thức của MongoDB giới thiệu replaceOne như một "đặc biệt" vua của update() hoạt động mà không cho phép việc sử dụng các toán tử nguyên tử như $set trong câu lệnh và sẽ lỗi nếu bạn thử.

Điều này rõ ràng hơn nhiều về mặt ngữ nghĩa kể từ khi thay thế đọc rất rõ ràng phương pháp này thực sự được sử dụng để làm gì. Trong các lệnh gọi API tiêu chuẩn tới update() tất nhiên, các biến thể vẫn cho phép bạn bỏ qua các toán tử nguyên tử và sẽ chỉ thay thế nội dung nào. Nhưng cần có cảnh báo.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. dịch vụ mongodb không khởi động

  2. Chuyển đổi ObjectID (Mongodb) thành Chuỗi trong JavaScript

  3. Sắp xếp MongoDB

  4. MongoDB - người dùng quản trị không được ủy quyền

  5. MongoDB $ lookup objectid nhận được mảng trống?