2016-11-15 14 views
1

mongo dbからいくつかの情報をロードして表示しようとしています。私のサイトはnode.js/expressで動作します。mongo dbの最初のテーブルの結果に基づいて2番目のテーブルからデータをロード

私は2つのテーブルを持っていますが、最初はパレットです。これはすべてロードして表示しますが、それはうまく動作します。しかし、各パレットについて、私は例のリストを持っています。私は各パレットをループし、そのパレットのすべての例を取得したいと思います。

私は間違いなく間違っています。find()メソッドが非同期であるため、余分なデータを取得する前にデータが送信されていると思います。しかし、複数回実行されているため、例のコールバックにrender関数を置くことはできません。

PHPでは、私は別のテーブルからデータを取り出し、共通のカラムに基づいて最初のテーブルに接続できるようにしていましたが、これをどうやって行うのかは分かりません手動でループを作成します。

/* GET palette database main page. */ 
router.get('/', function(req, res, next) { 
    console.log('rendering test page'); 
    var Palette = require('../models/paletteDatabase'); 

    //load all palettes 
    Palette.find({}, function(err, palettes) { 
    if (err) return next(err); 

    var PaletteExamples = require('../models/paletteExamples'); 

    for (var i = 0; i < palettes.length; i++) { 
     //split the colors into an array 
     palettes[i].colorsArray = palettes[i].colors.split(','); 

     PaletteExamples.find({paletteId: palettes[i]._id}, function(err, result) { 
     if (err) return next(err); 

     palettes[i].examples=result; 


     }); 
    } 

    res.render('palette-database', { 
     title: 'Palette List', 
     palettes: palettes, 
     css: 'palette-db', 
     js: 'palette-db' 
    }); 

    }); 

}); 
+0

この行の後にあなたの応答を送ってください 'palettes [i] .examples = result;' –

+0

その行はループ内にあり、複数回送信される(または最初に送信される) – stackers

+0

そしてあなたのforループを削除し、あなたのmongoリクエストで 'in'クエリを使用するのはどうですか? –

答えて

1

活用集約フレームワークで見つかった$lookup演算子を使用してクエリを取り外すことができる方法です。これにより、同じデータベース内の別のコレクションへの左外部結合が行われ、処理のために「結合」されたコレクションの文書がフィルター処理されます。次のように、この演算子を持つ集約パイプラインを実行することができ

:次期のMongoDB 3.4のリリースで

/* GET palette database main page. */ 
router.get('/', function(req, res, next) { 
    console.log('rendering test page'); 
    var Palette = require('../models/paletteDatabase'); 

    // load all palettes 
    Palette.aggregate([ 
     { 
      "$lookup": { 
       "from": "paletteExamples", // <-- collection name for examples 
       "localField": "_id", 
       "foreignField": "paletteId", 
       "as": "examples"     
      } 
     } 
    ]).exec(function(err, docs){ 

     var palettes = docs.map(function(doc){ 
      doc["colorsArray"] = doc.colors.split(','); 
      return doc; 
     }); 

     res.render('palette-database', { 
      title: 'Palette List', 
      palettes: palettes, 
      css: 'palette-db', 
      js: 'palette-db' 
     }); 
    }); 

}); 

を、あなたは内の新しいフィールドを導入することで、サーバー上の文字列分割を行うことができます次のように$split oprratorを用い$projectパイプライン:

// load all palettes 
Palette.aggregate([ 
    { 
     "$lookup": { 
      "from": "paletteExamples", 
      "localField": "_id", 
      "foreignField": "paletteId", 
      "as": "examples"     
     } 
    }, 
    { 
     "$project": { 
      "examples": 1, 
      "colorsArray": { "$split": ["$colors", ","] }, 
      /* project other fields as necessary */ 
     } 
    } 
]).exec(function(err, palettes){  
    res.render('palette-database', { 
     title: 'Palette List', 
     palettes: palettes, 
     css: 'palette-db', 
     js: 'palette-db' 
    }); 
}); 
+0

"例のコレクション名"とは何ですか、定義されている場所はどこですか?コードが何をしているのか分かりませんが、それを実行するとパレットは定義されません。 – stackers

+0

参照できる '$ lookup'演算子に関するドキュメントへのリンクを提供しました。 ''例のコメント ''コレクション名は '' paletteExamples'コレクションの名前、つまりMongooseモデル 'paletteExamples'の実際のMongoDBコレクション名で値を置き換えます。これはmongoシェルからdb 'show collections'コマンドを実行しています – chridam

+0

何らかの理由でコンソールから見つけられません。私のコードのどこかで定義する必要がありますか?これは私のモデルからですか? var PaletteExample = mongoose.model( 'PaletteExample'、paletteExampleSchema); – stackers

0

これは、forループ

var array = []; //your array 
PaletteExamples.find({'label': 
    {$in: array} 
    },function(err, examples){ 

    } 
関連する問題