我有一个 mongo 脚本,用于在数据库迁移后执行一些数据清理。
当我在本地运行此脚本时,它会在大约 5 分钟内完成。当我从我的本地机器针对远程实例运行脚本时,它需要永远(我通常在大约两个小时后将其终止)。这些数据库本质上是相同的。索引都是一样的,可能有几条记录在一个地方,而另一个地方没有。
我正在执行这样的脚本:
本地-
mongo localDatabase script.js
针对远程实例-
mongo removeServer/remoteDatabase -u user -p password script.js
我曾假设,由于我将脚本传递给远程实例,它将完全在远程机器上执行,而无需在远程机器和我的本地机器之间来回传输数据(因此会有性能差异不大)。
这个假设是否正确?知道为什么我看到本地/远程之间的巨大性能差异吗?有关如何修复的建议?
最佳答案
是的,您可以使用 Bulk operations ,MongoDB 中的所有操作都是围绕单个集合设计的,但是循环一个集合并插入或更新另一个集合并没有错。
事实上,在 MongoDB 2.6 shell 中,这是最好的方法,实际的收集方法本身尝试在幕后使用“批量”方法,即使它们实际上每次操作只执行单个更新/插入。这就是为什么您会在 shell 中看到不同的响应。
请注意,您的服务器也需要是 MongoDB 2.6 或更高版本的实例,这就是为什么 shell 中的收集方法会在您连接到较旧的服务器时进行一些检测的原因。
但基本上你的过程是:
var bulk = db.targetcollection.initializeOrderedBulkOP();
var counter = 0;
db.sourcecollection.find().forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne(
// update operations here
);
counter++;
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.targetcollection.initializeOrderedBulkOP();
}
});
if ( counter % 1000 != 0 )
bulk.execute();
Bulk API 本身将使您发送给它的所有操作“排队”,直到调用将操作发送到服务器的执行。 API本身只会将任何操作保留在“队列”中,直到它被调用,但实际上一次只发送 1000 个条目的批处理。为了避免用完额外的内存,这里要格外小心地用模数手动限制它。
您可以根据需要调整该数量,但请记住,确实存在 16MB 的硬性限制,因为这基本上转化为 BSON 文档作为请求。
查看所有选项的完整手册页,包括更新插入、多重更新、插入和删除。甚至是无序操作,其中单个错误的顺序或失败并不重要。
另请注意,后一种情况下的写入结果将返回列表中的错误项(如果有)以及包含应用更新插入列表等内容的响应。
结合让您的 shell 实例尽可能靠近服务器,减少的“来回”流量将加快速度。正如我所说,无论如何 shell 都会使用这些,因此您不妨利用这些来发挥您的优势。
关于javascript - Mongo 脚本在本地运行速度很快,但如果我针对远程实例运行它会很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25189652/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg