在 Meteor 或 Node 中批量插入 mongodb
Posted
技术标签:
【中文标题】在 Meteor 或 Node 中批量插入 mongodb【英文标题】:Bulk mongodb insert in Meteor or Node 【发布时间】:2013-11-14 11:08:41 【问题描述】:MongoDB支持批量插入http://docs.mongodb.org/manual/core/bulk-inserts/
我在 Meteor 收藏中试过了:
Orders.insert([
"cust_id" : "A123", "amount" : 500, "status" : "A", "_id" : "iZXL7ewBDALpic8Fj" ,
"cust_id" : "A123", "amount" : 250, "status" : "A", "_id" : "zNrdBAxxeNZQ2yrL9" ,
"cust_id" : "B212", "amount" : 200, "status" : "A", "_id" : "vev3pjJ8cmiDHHxe4" ,
"cust_id" : "A123", "amount" : 300, "status" : "D", "_id" : "BBLngRhS76DgeHJQJ"
]);
但它只是创建
"0" : "cust_id" : "A123", "amount" : 500, "status" : "A", "_id" : "iZXL7ewBDALpic8Fj",
"1" : "cust_id" : "A123", "amount" : 250, "status" : "A", "_id" : "zNrdBAxxeNZQ2yrL9" ,
"2" : "cust_id" : "B212", "amount" : 200, "status" : "A", "_id" : "vev3pjJ8cmiDHHxe4" ,
"3" : "cust_id" : "A123", "amount" : 300, "status" : "D", "_id" : "BBLngRhS76DgeHJQJ" ,
"_id" : "6zWayeGtQCdfS65Tz"
我需要它来进行性能测试。我需要用数千个测试项目填充和测试数据库。我在 foreach 中进行了插入,但是填充数据库需要很长时间。
这里有什么解决方法吗?或者我们可以期待 Meteor 在下一个版本中支持这一点吗?
【问题讨论】:
如果花费的时间太长,您可以并行运行多个客户端,每个客户端都从 forEach 循环发送文档 - 它的速度应该接近客户端进程的数量。 查看我对why-does-loading-data-into-a-meteor-collection-take-so-long的回复。 【参考方案1】:您可以使用 exec (nodejs docs) 在服务器上 Meteor.startup
内的流星内运行 mongo 脚本。
例子:
Meteor.startup(function ()
var exec = Npm.require('child_process').exec;
exec('mongo localhost:27017/meteor path-to/my-insert-script.js', function ( )
// done
);
);
不是最佳选择,但我认为这是您目前最好的选择。您还可以在 exec 中对 Mongo 使用命令行选项 --eval
,并将插入语句作为字符串传递给 exec。可能看起来像这样:
Meteor.startup(function ()
var exec = Npm.require('child_process').exec;
exec('mongo localhost:27017/meteor --eval \'db.Orders.insert(' + JSON.stringify(arrOfOrders) + ')\'', function ( )
// done
);
);
【讨论】:
谢谢,我使用了第二种变体。但是双引号必须是单引号,因为 JSON.stringyfy() 加了双引号会导致SyntaxError: Unexpected end of input
.
很高兴我能帮上忙。我没有测试过这两种解决方案。我会更新我的答案,使其在语法上更正确。
考虑使用mongoimport:***.com/questions/15365747/…【参考方案2】:
当向数据库中插入大量数据时,例如,在 forEach 循环中,您需要确保页面上没有依赖它的响应式内容。否则,反应式重新渲染会极大地减慢您的客户端速度。当所有模板都被禁用时,您可以在几分之一秒内轻松地将数千个文档插入到一个集合中,而如果发生相关反应,在客户端和服务器上的 CPU 都处于 100% 的情况下,相同的操作可能需要几分钟时间。
您可能希望向其内容取决于此数据的任何模板添加条件,例如:
Template.myTemplate.items = function()
if (Session.get("active"))
return Order.find();
然后您可以在 forEach 循环之前停用所有反应式重新渲染,然后再重新激活它 (Session.set("active", false))。
【讨论】:
这可能会有所帮助,但我不想重写每个模板。【参考方案3】:您可以使用 rawCollection,它是 Meteor.Collection 中的节点 mongodb 驱动程序实现。
await Orders.rawCollection().insertMany(arrOfOrders)
就我而言,它适用于 70M 数据。 (await 使其同步,因此您应该考虑是否将其用于您的目的。)
【讨论】:
以上是关于在 Meteor 或 Node 中批量插入 mongodb的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 mysljs 在 mySql 和 node.js 中批量插入