【问题标题】:In Meteor - how to do a bulk insert into a nested array在 Meteor - 如何批量插入嵌套数组
【发布时间】:2016-02-20 21:27:08
【问题描述】:

我正在尝试将数千条记录导入 Meteor 集合中的嵌套数组中。这是来自 JSON 对象的财务数据。我需要在插入它之前对其进行一些计算,所以不能这样做。为每次写入执行 $addToSet 操作非常非常慢。有没有办法在一次调用中推送完整的数据集?

我的架构看起来像这样。

NestedSchema = new SimpleSchema({
  item: {
    type: String
  },

   aThing: {
    type: Number
   }
});

MasterSchema = new SimpleSchema({
   symbol: {
     type: String,
     label: 'Symbol',
     unique: true
   },

   data: {
     type: [NestedSchema],
     optional: true
   }
});

我有一堆这样的数据要插入。

var dataToInsert = [{item: "thing", aThing: 1}, {item: "thing2", aThing: 2}, {item: "thing3", aThing: 2}];

我试图插入嵌套数组的数据是 5000 多条记录。我看过https://atmospherejs.com/udondan/bulk-collection-updatehttps://atmospherejs.com/mikowals/batch-insert,但它们似乎并没有完全符合我的要求。理想情况下,我有一个解决方案,可以在收集新记录时批量追加它们。

【问题讨论】:

  • 您是否使用$addToSet 来避免上当受骗?如果没有骗子,那么只需$push,那应该会快很多。或者你可以在内存中创建整个数组然后一次性插入吗?

标签: javascript arrays mongodb meteor


【解决方案1】:

您可以使用数组上的 forEach() 方法更新集合,并在循环内利用写入命令 Bulk API 来执行批量更新操作,这些操作只是抽象在服务器之上,以便轻松构建批量操作。这些批量操作主要有两种形式:

  • 有序批量操作。这些操作按顺序执行所有操作,并在第一次写入错误时出错。
  • 无序批量操作。这些操作并行执行所有操作并汇总所有错误。无序批量操作不保证执行顺序。

注意,对于早于 2.6 的旧服务器,API 将下转换操作。但是,不可能进行 100% 的下转换,因此可能存在一些无法正确报告正确数字的极端情况。您可以通过Mongo.Collection 上的rawCollectionrawDatabase 方法获得对npm MongoDB 驱动程序中的集合和数据库对象的原始访问权限

MyCollection = new Meteor.Collection("mycollection");

if (Meteor.isServer) {
    Meteor.startup(function () {
        Meteor.methods({
            insertData: function(symbol) {
                var bulkOp = MyCollection.rawCollection().initializeUnorderedBulkOp(),
                    counter = 0,
                    dataToInsert = [...];

                dataToInsert.forEach(function(data) {

                    bulkOp.find({"symbol": symbol}).updateOne({ "$addToSet": data });

                    counter++;
                    if (counter % 1000 == 0) {
                        // Execute per 1000 operations and re-initialize every 1000 update statements
                        bulkOp.execute(function(e, result) {
                            // do something with result
                            console.info('result.nMatched', result.nMatched, 'result.nModified', result.nModified);
                        });
                        bulkOp = MyCollection.rawCollection().initializeUnorderedBulkOp();
                    }
                }); 

                // Clean up queues
                if (counter % 1000 != 0){
                    bulkOp.execute(function(e, result) {
                        // do something with result
                    });
                }
            }
        }); 
    });
}

【讨论】:

  • @user3225576 不用担心,很乐意提供帮助:)
猜你喜欢
  • 2016-01-03
  • 1970-01-01
  • 2013-11-14
  • 2018-03-11
  • 2016-06-17
  • 2021-06-10
  • 1970-01-01
  • 2013-07-26
  • 2020-09-02
相关资源
最近更新 更多