Javascript MongoDB收集方法和数据库命令之间的性能差异是什么

Javascript MongoDB收集方法和数据库命令之间的性能差异是什么,javascript,mongodb,Javascript,Mongodb,虽然这篇文章回答了根本性的区别,但两者之间是否存在绩效差异?如果我使用的是MongoDB后端,那么方法和命令之间的折衷是什么,或者它们是否真的可以互换(至少对于更新、插入和删除而言)?一般情况下,两种形式都是相对可互换的。正如您参考的文章中的答案所述,您在mongo shell方法和驱动程序实现中看到的事实是,提供的方法实际上只是底层命令方法的包装,甚至类似于db.runCommand本身在某种程度上也是如此 因此,实际上,一切都只是将请求封送到BSON对象中以在系统$cmd集合上处理的一种手段

虽然这篇文章回答了根本性的区别,但两者之间是否存在绩效差异?如果我使用的是MongoDB后端,那么方法和命令之间的折衷是什么,或者它们是否真的可以互换(至少对于更新、插入和删除而言)?

一般情况下,两种形式都是相对可互换的。正如您参考的文章中的答案所述,您在mongo shell方法和驱动程序实现中看到的事实是,提供的方法实际上只是底层命令方法的包装,甚至类似于
db.runCommand
本身在某种程度上也是如此

因此,实际上,一切都只是将请求封送到BSON对象中以在系统
$cmd
集合上处理的一种手段。唯一真正需要考虑的是实现,您可能会将其视为开销,但您很可能真的应该做这些事情

例如,您可以深入研究mongo shell中的
.update()
实现,它将显示包装代码的“部分”。因此,一个主要片段:

if(!wc)
wc=this.getWriteConcern();
if(this.getMongo().writeMode()!=“legacy”){
var bulk=this.initializeOrderedBulkOp();
var updateOp=bulk.find(查询);
如果(向上插入){
updateOp=updateOp.upsert();
}
如果(多){
更新(obj);
}
否则{
updateOp.updateOne(obj);
}
试一试{
结果=bulk.execute(wc.toSingleResult();
}
捕获(ex){
if(批量写入错误的前实例| |写入命令错误的前实例){
结果=例如toSingleResult();
}
否则{
//引发的其他异常
掷骰子;
}
}
}
否则{
本文件为有效更新文件(obj);
this.getMongo().update(this.\u全名,查询,obj,
upsert?真:假,多?真:假);
//如果需要,强制执行写关注
如果(wc)
结果=this.runCommand(“getLastError”,wc instanceof WriteConcern?wc.toJSON():wc);
}
这是来自MongoDB 2.6版本。您可以在这里看到,这个“助手”实质上试图将请求参数“包装”到一个新样式的“批量”操作中。即使是“单数”而不是批量,这里的目的是利用提供的“写关注点”响应

考虑到性能,可以在不使用实现的情况下发出请求,该实现基本上在代码中的“遗留”实现中显示,并调用

这意味着调用本身本质上是“触发并忘记”,虽然您可以显式地设置这种级别的“写关注点”,但对方法的一般调用实际上并不等待请求本身。实现的是“写关注点”级别的“getLastError”调用,它实际上“等待”请求处理并返回诸如“发现”、“修改”、“插入”或“删除”之类的信息

在一天结束时,您可以发出原始命令或执行自己的实现,而这些实现没有考虑到这些事情,只是您所有操作的快速“开火并忘记”版本。但是,尽管如此,这可能不是您在应用程序中真正想要做的事情,因为您要么想要提供的“耐久性”,要么只是简单地通过设置适合您的情况的“写关注点”,将耐久性“调优”到您所需的级别


此外,对于除“Read”或
.find()
之外的所有常规“CRUD”操作,“Bulk”操作通过将多个请求合并为一个“over-the-wire”请求,为您提供了最佳性能提升。这本身就是最好的性能提升,而不必等待每个操作的响应。因此,它看起来确实值得单独使用与“原始”命令相反的命令。

如果驱动程序编程良好,那么方法实际上应该只是命令的助手