2

我正在使用node-csv-parser读取 csv 数据并使用 mongoose 将其存储在 mongodb 中。但是我正在尝试加快导入速度,并且我想使用 公开的本机保存方法进行评估node-mongodb-native,在 mongoose 中使用Model.collection. (这是根据我在 Mongo 总部办公时间与之交谈的一位 mongo 工程师的建议)。

node-csv-parserdata每次读取 csv 的新行时触发一个事件。在这个事件中,我读入数据行,从中创建一个新数据点,并将其保存在 mongo.xml 中。data我可以使用我的 mongoose 模型在事件中很好地保存数据点TestDataPoint。但是,如果我尝试为数据点创建一个 javascript 对象并使用 保存它TestDataPoint.collection.save,我会收到错误:RangeError: Maximum call stack size exceeded.

我尝试以各种不同的方式调用此本地保存,包括直接通过获取集合mongoose.connection.db.collection("testdatapoints")并将其发送到异步模块提供的队列,但总是或多或少相同的结果。我可以在代码的其他地方使用本机驱动程序成功保存数据点,甚至在endcsv 导入的事件中,而不是在data事件中。

我还通过记录我当前的设置(64 位 AMD 处理器上的 Ubuntu 12.04,8 gb RAM)确定,代码在抛出堆栈错误之前迭代了 csv 的 154 行,但是没有数据写入数据库从这个data事件内部。似乎无意中发生了某种递归(?),或者它可能是 node-csv-parser 和 node-mongodb-native 之间的某种错误。

为了澄清,使用下面的(编辑/更新)示例代码,日志重复 154 次:

about to call native save
just called native save

然后说:

in native save callback for dataPoint: 1
Native save failed, error:RangeError: Maximum call stack size exceeded
in native save callback for dataPoint: 2
Native save failed, error:RangeError: Maximum call stack size exceeded

直到dataPoint 154,然后它重复“即将调用/刚刚调用”另外154次,然后记录dataPoints 155-308的错误等等(我有很多数据点要导入)。这个 154 数字是相当可重复的,我想我已经观察到它一次或两次通过 155 行。

有人建议我将保存调用包装在 aprocess.nextTick()中以清除堆栈。当我尝试这样做时,在我的日志中我可以看到 save 被调用了 154 次,然后process.nextTick()被调用了 154 次,然后 RangeError 被记录了 154 次,并且序列重复。

我正在运行节点 0.8.2、mongoose 2.7.2 和 mongodb 2.0.4。

csv()
    .fromPath(path)
    .on("data", (data, index) ->

        # cellTest is an instance of a Mongoose model object
        newDataPoint = 
            testId: cellTest.testId    # this assignment was causing recursion in the native save
            dataPoint: data[1]
            testTime: data[2]/3600
            cycleIndex: data[3]

        console.log "about to call native save"

        # TestDataPoint is my my mongoose model, which saves fine, but
        # this call throws the RangeError: Maximum stack size exceeded
        TestDataPoint.collection.save newDataPoint, safe:true, (err, dataPoint) ->
            console.log "in native save callback for dataPoint: " + data[1]
            if err
                console.log "Native save failed, error:" + err

        console.log "just called native save"

    .on("end", (count) ->
        newDataPoint = 
            dataPoint: 100            # dummy values
            testTime: 200
            cycleIndex: 300

        # This call works, saves the data point
        TestDataPoint.collection.save newDataPoint, safe:false, null
    )
    .on("error", (err) ->
       console.log err
    )

编辑:解决了!

那作业:

testId: cellTest.testId

导致保存递归。与 cellTest 是另一个 Mongoose 模型的实例有关。将分配更改为:

testId: parseInt(cellTest.testId)

消除了递归并允许执行保存。

4

1 回答 1

1

此问题已得到解决。在我的实际代码中,我将属性之一设置为newDataPoint等于另一个 Mongoose 模型对象的整数属性。(下次我会知道不要从我的样本中“简化”那个细节!)这在某种程度上导致了保存递归。

parseInt()我通过围绕该值的分配来修复它。保存工作正常,比使用 Mongoose 快大约 3 倍(我知道我放弃了不使用 Mongoose 的一些东西,但对于我记录大量数据点的应用程序来说很好,其中没有单点是全部那很重要)。

于 2012-07-20T18:50:52.507 回答