2016-08-17 9 views
1

Mongooseモデルを使ってMongoDBに文書を挿入しようとしていますが、私は約束を使用したいと思います。このデータはMSSQLデータベースに由来するため、各セット内のドキュメントは他のセット内のドキュメントと外部キーの関係にあります。ここでPromise.all複数のモンゴーズ文書挿入配列の配列

はサンプルコードです:

const Promise = require('bluebird'); 
const mongoose = require('mongoose'); 
const Make = Promise.promisifyAll(require('../models/make-model')); 
const Nameplate = Promise.promisifyAll(require('../models/nameplate-model')); 
const Vehicle = Promise.promisifyAll(require('../models/vehicle-model')); 

const { makes, nameplates, vehicles } = require('./sqlExport.json'); 

const logErr = (err) => console.error(err); 

Promise.resolve(
    mongoose.connection.db.dropDatabase() 
) 
.then(() => (
    Promise.all(
    makes.map(make => (
     Make.create(make).then(makeRes => console.log(`Created make ${makeRes}`)) 
    )) 
)), 
    logErr 
) 
.then(() => (
    Promise.all(
    nameplates.map(nameplate => { 
     const { sqlMakeId, sqlModelId, sqlSubModelId } = nameplate; 
     return Make.find({ sqlMakeId }) 
     .then(makeRes => { 
      if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for make.sqlMakeId: ${sqlMakeId}`); 
      const finalNameplate = Object.assign({}, nameplate, { mongoMakeId: makeRes[0]._id }); 
      return Nameplate.create(finalNameplate); 
     }) 
     .then(nameplateRes => { 
      console.log(`Created nameplate ${nameplateRes}`); 
     }); 
    }) 
)), 
    logErr 
) 
.then(() => (
    Promise.all(
    vehicles.map(vehicle => { 
     const { sqlVehicleId, sqlMakeId, sqlSubModelId } = vehicle; 
     const extraParams = {}; 
     return Make.find({ sqlMakeId }) 
     .then(makeRes => { 
      if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for make.sqlMakeId: ${sqlMakeId}`); 
      extraParams.mongoMakeId = makeRes[0]._id; 
      return Nameplate.find({ sqlSubModelId }); 
     }) 
     .then(nameplateRes => { 
      if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for nameplate.sqlSubModelId: ${sqlSubModelId}`); 
      extraParams.mongoNameplateId = nameplateRes[0]._id; 
      const finalVehicle = Object.assign({}, vehicle, extraParams); 
      return Vehicle.create(finalVehicle); 
     }) 
     .then(vehicleRes => { 
      console.log(`Created vehicle ${vehicleRes}`); 
     }); 
    }) 
)), 
    logErr 
) 
.catch(logErr); 

問題は時々車両が銘板インサートのいずれかの前に、すべての実行を挿入し、ひいてはmongoNameplateIdの正しい文書の_idを見つけることができないということです。

完全なコードはここにある:私はそれが私のマングースと青い鳥の下に次の行を追加することで動作するようになったhttps://gist.github.com/jeremyjs/1d5509350d3cae69d0e83f1d6478eeb2

+0

は私にとってうまくいくようです。デバッグを容易にするために、コードをベアボーンに落とすことができれば助けになります。私がしたいことの一つは、すべての非同期呼び出しを1秒後に約束を解決するsetTimeout呼び出しで置き換えて、置き換えているもののメッセージを表示することです。つまり、 'console.log(" Make.find( 'blah') " ) ' – thedarklord47

+2

' Nameplate'と 'Vehicle' APIは約束されていますが、約束されたメソッドが呼び出されたという証拠はありません。 'Nameplate.create()'は 'Nameplate.createAsync()'、 'Vehicle.create()'は 'Vehicle.createAsync()'であるべきですか? –

+1

@ Roamer-1888よろしくお願いします。私はブルーバードを使用したことはありませんが、ドキュメントを見ると、オブジェクトの元のメソッドは上書きされませんが、Async-suffixを使用して新しいメソッドが作成されることに注意してください。たとえば、promisifyAllの場合、node.js fsオブジェクトはfs.statAsyncを使用してpromisified statメソッドを呼び出します。 – thedarklord47

答えて

0

は、ステートメントが必要です。ここ

mongoose.Promise = Promise;

ドキュメント:http://mongoosejs.com/docs/promises.html

でその場合、ブルーバードのPromise.promisifyAllパターンは必要ありませんでした。

+0

うまく簡単ですが、それがうまくいく場合、デフォルトの 'mpromise'も機能するようです。あなたはBluebirdもそのmongoose.Promise = Promise行も試してみましたか? –

+0

@ Roamer-1888実際にはmpromiseで動作しますが、Bluebirdはmpromiseよりパフォーマンスが優れています。 –