在node-csv-parser中调用node-mongodb-native:RangeError:超出最大调用堆栈大小

我使用node-csv-parser读取csv数据,并使用mongoose将它存储在mongodb中。 但是我试图加快导入,并且我想使用node-mongodb-native公开的本地保存方法进行评估,使用Model.collection以mongoose访问。 (这是我在Mongo总部的办公时间与一位蒙古工程师的build议)。

每次读入csv的新行时, node-csv-parser触发一个data事件。 在这个事件里面,我读了一行数据,从中创build一个新的数据点,并保存在mongo中。 我可以使用我的mongoose模型TestDataPointdata事件内保存数据点。 但是,如果我尝试改为创build一个javascript对象的数据点,并保存使用TestDataPoint.collection.save ,我得到的错误: RangeError: Maximum call stack size exceeded

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

我也通过logging来确定,在我当前的设置(64位AMD处理器上的Ubuntu 12.04,8 GB RAM)上,代码在抛出堆栈错误之前迭代了154行csv,但没有数据写入数据库从这个data事件里面。 似乎无意中发生了某种recursion(?),或者也许是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 

直到数据点154,然后重复“关于调用/刚刚调用”另外154次,然后logging数据点155-308的错误等(我有很多数据点导入)。 这154个数字是相当可重复的,我以为我曾经观察过一次或两次155行。

有人build议我将save调用包装在process.nextTick()来清除堆栈。 当我尝试的时候,在我的日志中,我可以看到保存被调用了154次,然后process.nextTick()被调用了154次,然后RangeError被logging了154次,然后重复序列。

我正在运行节点0.8.2,mongoose2.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 

导致recursion保存。 与cellTest是另一个Mongoose模型的实例有关。 将作业更改为:

 testId: parseInt(cellTest.testId) 

消除了recursion,并允许执行保存。

此问题已得到解决。 在我的实际代码中,我将newDataPoint一个属性设置为另一个Mongoose模型对象的整数属性。 (下一次,我会知道不要“简化”我的示例中的细节!)这是以某种方式导致保存recursion。

我通过在该值的赋值周围包装一个parseInt()来修复它。 保存工作正常,比使用Mongoose快大约3倍(我知道我放弃了一些不使用Mongoose的东西,但对我的应用程序来说,我logging了很多没有单一点的数据点那很重要)。