node-csv-parserを使用してcsvデータを読み込み、mongooseを使用してmongodbに保存しています。node-mongodb-native
ただし、インポートを高速化しようとしているので、を使用してマングースでアクセスされる、によって公開されたネイティブの保存メソッドを使用して評価したいと思いますModel.collection
。(これは、モンゴ本社の営業時間に話したモンゴエンジニアのアドバイスによるものです)。
node-csv-parser
data
csvの新しい行を読み取るたびにイベントを発生させます。このイベント内で、データの行を読み取り、そこから新しいデータポイントを作成し、mongoに保存します。data
マングースモデルを使用して、イベント内にデータポイントを適切に保存できますTestDataPoint
。ただし、代わりにデータポイントのjavascriptオブジェクトを作成し、を使用して保存しようとするとTestDataPoint.collection.save
、次のエラーが発生しますRangeError: Maximum call stack size exceeded
。
コレクションを直接取得したり、非同期モジュールmongoose.connection.db.collection("testdatapoints")
によって提供されるキューに送信したりするなど、さまざまな方法でこのネイティブ保存を呼び出してみましたが、結果はほぼ同じです。コードの他の場所でネイティブドライバーを使用してデータポイントを正常に保存できます。また、イベント内ではなく、csvインポートのイベント内でも正常に保存できます。end
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行を1〜2回通過するのを観察したと思います。
process.nextTick()
スタックをクリアするために、save呼び出しをでラップすることが提案されました。これを試してみると、ログで、保存が154回呼び出され、次にprocess.nextTick()
154回呼び出され、次にRangeErrorが154回ログに記録され、シーケンスが繰り返されることがわかります。
ノード0.8.2、mongoose 2.7.2、mongodb2.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と関係があります。割り当てを次のように変更します。
testId: parseInt(cellTest.testId)
再帰を排除し、保存を実行できるようにしました。