Node.js中数据库Mongoose更新的最佳实践?
假设我有以下模式:Node.js中数据库Mongoose更新的最佳实践?,node.js,performance,mongoose,code-readability,Node.js,Performance,Mongoose,Code Readability,假设我有以下模式: const mySchema = mongoose.Schema({ _id: mongoose.Schema.Types.ObjectId, date: Number, data: { field1 : Number, field2 : Number } }); 我想为具有“myAwesomeDate”的文档用“myAwesomeValue”更新字段2。我当前在异步/等待函数中的代码是: // V1 var
const mySchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
date: Number,
data: {
field1 : Number,
field2 : Number
}
});
我想为具有“myAwesomeDate”的文档用“myAwesomeValue”更新字段2。我当前在异步/等待函数中的代码是:
// V1
var myAwesomeDocument = await myModel.findOneAndUpdate(
{date: myAwesomeDate}, //selector
{$set: { //update
'data.field2': myAwesomeValue
}},
{ //options
upsert: false,
new: true
}
).exec();
此代码允许我使用更新的文档
如果我没有弄错的话,下面的代码具有相同的行为,但是要避免,因为它首先将文档加载到客户端(因此效率较低)():
现在,我想使用.doSomething()使我的代码更具可读性:
// V3 (any code mistake here ?)
var myAwesomeDocument = await myModel.findOne({date: myAwesomeDate})
.set(
{'data.field2': myAwesomeValue},
{upsert: false, new: true}
)
.exec();
我的问题首先是关于效率,然后是关于代码可读性:
- 有没有比V1更高效的代码李>
- V3是否执行相同的更新?它和V1一样高效吗
- 有没有一种更有效、更可读的方法来编写V3
谢谢你的回答 根据您提供的示例,效率最高的是v1
- 引擎盖下的V1只会触发一个查询,mongo's
- V2需要2次查询才能完成预期的更新。那么芬顿 updateOne
- V3并没有做预期的事情,它只是做了findOne,而不是findOne 正在对找到的文档发出任何更新操作
instance = await model
.findOneAndUpdate({date})
.set({'data.f2': f1},)
.setOptions({new: true})
.exec();
说明:
Mongoose findOneAndUpdate返回a(检查示例)。然后,我们使用查询的方法来设置更新操作和选项
总之,您可以使用V1,也可以使用我提供的更新的V3,因为它们在后台使用相同的数据库调用
您始终可以使用来分析实际发送到数据库的查询
为了支持我上面所说的,下面是我用来运行测试的代码片段。您可以像这样调用它:
consturi='1〕mongodb://localhost:27017/test-萨夫;
const mongoose=require('mongoose');
常量计数=进程argv[2]?parseInt(process.argv[2]):1;
const debug=process.argv[3]='true';
施工日期=1234567;
常数f1=1;
常数f2=2;
let模型;
(异步函数(){
wait mongoose.connect(uri,{useNewUrlParser:true,useUnifiedTopology:true});
const schema=new mongoose.schema({
日期:年月日,
数据:{
f1:数字,
f2:编号,
}
});
model=mongoose.model('model',schema);
console.log(“####开始###”)
const doc1=等待轰炸(v1,轰炸计数);
控制台日志(doc1);
const doc2=等待轰炸(v2,轰炸计数);
控制台日志(doc2);
const doc3=等待轰炸(v3,轰炸计数);
控制台日志(doc3);
const doc4=等待轰炸(v4,轰炸计数);
控制台日志(doc4);
console.log(“#########”);
})().catch(error=>console.error(error)),然后(()=>process.exit(1));
异步函数v1(){
console.log(“####V1####\n”);
在每个之前等待();
console.time(“####V1###”);
让实例=wait model.findOneAndUpdate(
{date},
{
$set:{
“data.f2”:f1,
},
},
{
厄普塞特:错,
新:真的
}
).exec();
console.timeEnd(“####V1###”);
等待每一次();
返回实例;
}
异步函数v2(){
console.log(“####V2####\n”);
在每个之前等待();
console.time(“#####V2###”);
让instance=wait model.findOne({date}).exec();
instance.data.f2=f1;
instance=等待instance.save();
console.timeEnd(“#####V2###”);
等待每一次();
返回实例;
}
异步函数v3(){
console.log(“####V3####\n”);
console.time(“#####V3###”);
在每个之前等待();
让实例=等待模型
.findOne({date})
.设置(
{'data.f2':f1},
{upsert:false,new:true}
).exec();
console.timeEnd(“####V3###”);
等待每一次();
返回实例
}
异步函数v4(){
console.log(“####V4###\n”);
控制台。时间(“####V4###”);
在每个之前等待();
让实例=等待模型
.findOneAndUpdate({date})
.set({'data.f2':f1})
.setOptions({new:true})
.exec();
console.timeEnd(“#####V4###”);
等待每一次();
返回实例;
}
异步函数beforeach(){
等待新型号({
日期,
数据:{
f1,
f2,
},
}).save();
mongoose.set('debug',debug);
}
异步函数afterEach(){
mongoose.set('debug',debug);
wait model.deleteMany({});
}
异步函数轰击(f,次){
设x;
for(设i=0;i }
我认为第一个是最好的选择。在数据库上做任何事情都是一个很好的实践,以避免在客户端上操作时出现问题,对数据库的请求越少,效率就越高(速度和一致性)!现在我了解了V3中的错误,以及如何通过.appendSomething()符号构建查询!非常感谢您花时间准确回答!你收到赏金了吗?
instance = await model
.findOneAndUpdate({date})
.set({'data.f2': f1},)
.setOptions({new: true})
.exec();