node.js – Mongoose覆盖文档而不是`$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',}

删除未指定的属性.

我怎么做?

解决方法

实际上,但是由于mongoose实际上“搞乱”了更新,这实际上是你提交给常规MongoDB函数认操作.

因此,mongoose认为它“明智”是一种“假设”你想要在这里发出$set指令的便利方法.由于在这种情况下您实际上不想这样做,因此在传递给任何.update()方法的选项中通过{overwrite:true}关闭该行为:

作为一个完整的例子:

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',_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' } },upsert: false,remove: false,fields: {} })
{
  "_id": "596efb0ec941ff0ec319ac1e","name": "Bill S. Preston","__v": 0
}
Mongoose: tests.findAndModify({ _id: ObjectId("596efb0ec941ff0ec319ac1e") },overwrite: true,"name": "Dan Smith"
}

显示文档被“覆盖”,因为我们抑制了$set操作,否则将被插值.这两个样本首先显示没有覆盖选项,后者应用$set修饰符,然后“使用”覆盖选项,其中传递了为“更新”传递的对象,并且不应用此类$set修饰符.

注意,这是MongoDB节点驱动程序“认”执行此操作的方式.因此,添加“隐式”$set的行为是由猫鼬完成的,除非你告诉它不要.

相关文章

这篇文章主要介绍“基于nodejs的ssh2怎么实现自动化部署”的...
本文小编为大家详细介绍“nodejs怎么实现目录不存在自动创建...
这篇“如何把nodejs数据传到前端”文章的知识点大部分人都不...
本文小编为大家详细介绍“nodejs如何实现定时删除文件”,内...
这篇文章主要讲解了“nodejs安装模块卡住不动怎么解决”,文...
今天小编给大家分享一下如何检测nodejs有没有安装成功的相关...