简体   繁体   English

在 Meteor 或 Node 中批量插入 mongodb

[英]Bulk mongodb insert in Meteor or Node

MongoDB supports bulk insert http://docs.mongodb.org/manual/core/bulk-inserts/ MongoDB 支持批量插入http://docs.mongodb.org/manual/core/bulk-inserts/

I have tried it in Meteor collection:我在 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" }
]);

but it creates just但它创造了

{ "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" }

I need it for performance testing purposes.我需要它用于性能测试。 I need to fill and test database with thousands of testing items.我需要用数千个测试项目填充和测试数据库。 I do inserts in foreach, but it takes too long to fill database.我在 foreach 中插入,但填充数据库需要很长时间。

Is here any workaround?这里有任何解决方法吗? Or can we expect Meteor will support this in next versions?或者我们可以期待 Meteor 会在下一个版本中支持这个吗?

You could use exec ( nodejs docs ) to run a mongo script inside of meteor inside of a Meteor.startup on the server.您可以使用 exec ( nodejs docs )在服务器上的Meteor.startup内的Meteor.startup内运行 mongo 脚本。

Example:例子:

Meteor.startup(function () {
    var exec = Npm.require('child_process').exec;
    exec('mongo localhost:27017/meteor path-to/my-insert-script.js', function ( ) {
       // done
    });        
});

Not optimum, but I think it's your best bet for now.不是最佳选择,但我认为这是您目前最好的选择。 You can also use the command line option --eval against Mongo in exec and pass the insert statement as a string to exec.您还可以在 exec 中对 Mongo 使用命令行选项--eval并将插入语句作为字符串传递给 exec。 That might look like this:这可能看起来像这样:

Meteor.startup(function () {
    var exec = Npm.require('child_process').exec;
    exec('mongo localhost:27017/meteor --eval \'db.Orders.insert(' + JSON.stringify(arrOfOrders) + ')\'', function ( ) {
       // done
    });        
});

When inserting a lot of data into the DB, eg, in a forEach loop, you want to make sure that there is no reactive content on your page that depends on it.当向数据库中插入大量数据时,例如在 forEach 循环中,您需要确保页面上没有依赖于它的反应性内容。 Otherwise the reactive rerendering is going to slow your client down tremendously.否则,反应式重新渲染会极大地减慢您的客户端的速度。 You can easily insert several thousand document into a collection in a fraction of a second when all templates are disabled, while the same operation can take several minutes with your CPU at 100% on both the client as the server if there is relevant reactivity happening.当所有模板都被禁用时,您可以在几分之一秒内轻松地将数千个文档插入到一个集合中,而如果发生相关反应,则相同的操作可能需要几分钟时间,并且客户端和服务器上的 CPU 均处于 100%。

You may want to add a condition to any template whose content depend on this data such as:您可能希望向其内容取决于此数据的任何模板添加条件,例如:

Template.myTemplate.items = function() {
  if (Session.get("active")) {
      return Order.find();
  }
}

Then you can deactivate all reactive rerendering before your forEach loop and reactivate it again afterwards (Session.set("active", false)).然后,您可以在 forEach 循环之前停用所有反应式重新渲染,然后再重新激活它(Session.set("active", false))。

You could use rawCollection which is node mongodb driver implemetation in Meteor.Collection.您可以使用 rawCollection,它是 Meteor.Collection 中的节点 mongodb 驱动程序实现。

await Orders.rawCollection().insertMany(arrOfOrders)

It works on 70M data in my case.就我而言,它适用于 70M 数据。 (await makes it synced so you should consider to use it or not for your purpose.) (await 使其同步,因此您应该考虑是否出于您的目的使用它。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM