2016-09-19 16 views
0

私のモデルは各オブジェクト間に多くの関係があり、いくつかのデータを検索する際には前のオブジェクトを見つけなければならず、多くのコールバックを書くことができます。Mongoose複数同期検索オブジェクトID

  1. 会社::ちょうど1つのフィールド、会社名フィールド
  2. ジオロケーション:二つのフィールド、緯度/経度
  3. オフィス:名前、住所

    は私が4つのモデルを持っています2つのObjectID:ジオロケーションオブジェクトIDと会社オブジェクトID

  4. ユーザー:電子メール、パスワードなど...オフィスオブジェクトID

次に、緯度/経度ごとに情報(名前、オフィス名、会社名など)を持つ最も近いユーザーを取得する必要があります。そして、地獄からの結果のコールバックがあります。

// Find all Geolocation 
    Geolocation.find({}, function(err, geolocations) { 
     if (err) throw err; 

     var array = []; 

     // Loop on geolocations object 
     Async.each(geolocations, function(origin, callback){ 

      var myJson = {"latitude":43.686978, "longitude":7.201922}; 

      // Calculate distance between two points 
      var geo = geolib.getDistance(
       {latitude: origin.latitude, longitude: origin.longitude}, 
       {latitude: myJson.latitude, longitude: myJson.longitude} 
      ); 

      // Find the office with the current geolocation object ID 
      Office.findOne({ geolocation: origin._id}, function(err, office){ 
       if (err) throw err; 

       // Find the company with the current office object ID 
       Company.findOne({ _id: office.company }, function(err, company){ 
        if (err) throw err; 

        // Find the user with the current office object ID 
        User.findOne({office: office._id}, function(err, user){ 
         if (err) throw err; 

         array.push({ 
          user: user.firstname+' '+user.lastname, 
          office: office.name, 
          company: company.name, 
          distance: geo 
         }); 

         callback(); 
        }); 
       }); 
      }); 

     }, function(err) { 
      array.sort(function (a, b) { 
       return a.distance - b.distance; 
      }); 

      for (var i = 0; i < array.length; i++){ 
       console.log(array[i]) 
      } 
     }); 

    }); 

私はasyncを使用していますが、それはループが終了したときとeach()方法が最も最も適切であるかどうかを知るための良い方法だ場合、私は知りません。

ご覧のとおり、私はオブジェクトIDを取得し、ユーザーがすべての情報を取得するために再度検索する必要があります。

あなたのコードをきれいにするアイデアはありますか?私のモデルでオブジェクトIDを使用しないでください。

答えて

0

それぞれfindOne関数を約束し、Babelのawaitを使用することができます。

let office = await new Promise((resolve, reject) => { 
    Office.findOne({ geolocation: origin._id}, function(err, office){ 
     if (err) reject(err) 
     resolve(office) 
}); 

let company = await new Promise((resolve, reject) => { 
    Company.findOne({ _id: office.company }, function(err, company){ 
     if (err) reject(err) 
     resolve(company) 
}); 
... and so on 

または、多分あなたはMongoDBのの人口について読みたい:この場合、あなたのコードは次のように見えるかもしれhttp://mongoosejs.com/docs/populate.html

+0

移入機能缶に直接必要なオブジェクトを返しますか?それはいいと思われる。しかし、私たちはどのようにして人口を2つにすることができます私は一度のモデルで2つのオブジェクトIDを持っているので? – John

+0

同時に2つ以上のフィールドに入力することができます。この 'Story'のようにしてください。 ' .find(...) ' ' .populate( 'fans _creator')//スペースで区切られたパス名 ' ' .exec() ' – Pter

関連する問題