stk*_*flw 7 mongoose mongodb node.js
说,我有一份文件:
{
_id: 'some_mongodb_id',
name: 'john doe',
phone: '+12345678901',
}
Run Code Online (Sandbox Code Playgroud)
我想更新这个文件:
.findOneAndUpdate({_id: 'some_mongodb_id'}, {name: 'Dan smith'})
Run Code Online (Sandbox Code Playgroud)
结果应该是这样的:
{
_id: 'some_mongodb_id',
name: 'Dan smith',
}
Run Code Online (Sandbox Code Playgroud)
应删除未指定的属性.
我怎么做?
Nei*_*unn 10
实际上,但是由于mongoose实际上"搞乱"了更新,这实际上是你提交给常规MongoDB函数的默认操作.
因此,mongoose认为它"明智"是一种"假设"你想要$set在这里发出指令的便利方法.由于在这种情况下您实际上不想这样做,因此您可以{ overwrite: true }在传递给任何.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();
}
})()
Run Code Online (Sandbox Code Playgroud)
生产:
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"
}
Run Code Online (Sandbox Code Playgroud)
显示文档被"覆盖",因为我们抑制了$set本来会被插值的操作.这两个样本首先显示没有overwrite选项,它应用$set修饰符,然后"with" overwrite选项,其中传递了为"更新"传入的对象,并且不应用此类$set修饰符.
注意,这是MongoDB节点驱动程序"默认"执行此操作的方式.所以添加"隐式"的行为$set是由猫鼬完成的,除非你告诉它不要.