복붙노트

[MONGODB] 문서를 덮어 몽구스 오히려 $ set` 필드는`그

MONGODB

문서를 덮어 몽구스 오히려 $ set` 필드는`그

말, 나는 문서를 가지고 :

{
  _id: 'some_mongodb_id',
  name: 'john doe',
  phone: '+12345678901',
}

나는이 문서를 업데이트하려면 :

.findOneAndUpdate({_id: 'some_mongodb_id'}, {name: 'Dan smith'})

그리고 그 결과는 다음과 같아야합니다

{
  _id: 'some_mongodb_id',
  name: 'Dan smith',
}

속성은, 지정되지 않은 그, 제거해야합니다.

어떻게 그렇게 할 수 있습니까?

해결법

  1. ==============================

    1.사실,하지만 몽구스는 내부적으로 업데이트 "장난"실제로는 사실, 이것은 실제로 일반 MongoDB의 기능에 제출의 기본 동작입니다.

    사실,하지만 몽구스는 내부적으로 업데이트 "장난"실제로는 사실, 이것은 실제로 일반 MongoDB의 기능에 제출의 기본 동작입니다.

    그래서 몽구스하다고 판단, 그것은 "가정"의 편의를 위해 방법으로 "현명한"당신은 여기에 $ 세트 명령을 발행하는 것을 의미했다. 어떤 .update를 () 메서드에 전달 된 옵션에서 : 당신이 실제로이 경우에는 그렇게하고 싶지 않기 때문에, 당신은 {진정한 덮어 쓰기}를 통해 그 동작을 해제 :

    전체 예를 들어 :

    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();
      }
    
    })()
    

    생성합니다 :

    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"
    }
    

    우리가 다른 보간되었을 $ 집합 연산을 억제하기 때문에 문서를 표시하는 것은 "덮어 쓰기"입니다. 두 샘플은 덮어 쓰기는 "갱신"에 대한 전달 된 객체가 존경 옵션, 그리고 그러한 $ 세트 수정이 적용되지 않습니다 "와"다음 $ 세트 수정을 적용하고, 덮어 쓰기 옵션없이 먼저 보여줍니다.

    참고이는 MongoDB의 노드 드라이버가이 "기본적으로"수행 방법이다. 은 "암시"$ 세트에 추가 할 수있는 행동이 몽구스에 의해 수행되고 그래서, 당신이하지 않으면하지 말 것을 말한다.

  2. ==============================

    2.당신은 upsert 옵션을 전달할 수 있으며, 문서를 대체합니다 :

    당신은 upsert 옵션을 전달할 수 있으며, 문서를 대체합니다 :

    var collection = db.collection('test');
    collection.findOneAndUpdate(
      {'_id': 'some_mongodb_id'},
      {name: 'Dan smith Only'},
      {upsert: true},
      function (err, doc) {
        console.log(doc);
      }
    );
    

    그러나 여기에서 문제는 - 콜백에서 문서가 문서를 찾았지만 업데이트되지 않는 것입니다. 따라서이 같은 일을 수행 할 필요가 :

    var collection = db.collection('test');
    collection.update(
      {'_id': 'some_mongodb_id'},
      {name: 'Dan smith Only'},
      {upsert: true},
      function (err, doc) {
        collection.findOne({'_id': 'some_mongodb_id'}, function (err, doc) {
            console.log(doc);
        });
      }
    );
    
  3. from https://stackoverflow.com/questions/45182011/mongoose-overwrite-the-document-rather-that-set-fields by cc-by-sa and MIT license