我正在使用node-csv-parser读取 csv 数据并使用 mongoose 将其存储在 mongodb 中。但是我正在尝试加快导入速度,并且我想使用 公开的本机保存方法进行评估node-mongodb-native
,在 mongoose 中使用Model.collection
. (这是根据我在 Mongo 总部办公时间与之交谈的一位 mongo 工程师的建议)。
node-csv-parser
data
每次读取 csv 的新行时触发一个事件。在这个事件中,我读入数据行,从中创建一个新数据点,并将其保存在 mongo.xml 中。data
我可以使用我的 mongoose 模型在事件中很好地保存数据点TestDataPoint
。但是,如果我尝试为数据点创建一个 javascript 对象并使用 保存它TestDataPoint.collection.save
,我会收到错误:RangeError: Maximum call stack size exceeded
.
我尝试以各种不同的方式调用此本地保存,包括直接通过获取集合mongoose.connection.db.collection("testdatapoints")
并将其发送到异步模块提供的队列,但总是或多或少相同的结果。我可以在代码的其他地方使用本机驱动程序成功保存数据点,甚至在end
csv 导入的事件中,而不是在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)
消除了递归并允许执行保存。