0

postgres を使用してノード js で次のコードを実行して、次のようなネストされた json オブジェクトのリストを取得しようとしています。

{
    "elements": [
        {
            "name": "element 1",
            "description": "lorem ipsus",
            "docs": [
                {
                    "docs_id": 1053,
                    "docs_file": "../uploads/1461s444---planimetria.pdf",
                    "docs_created_at": "ThuMay14201506: 00: 00GMT+0200(CEST)"
                },
                {
                    "docs_id": 1054,
                    "docs_file": "../uploads/1461s444---VAX-with-highlight.pdf",
                    "docs_created_at": "ThuMay14201506: 00: 00GMT+0200(CEST)"
                },
                {
                    "docs_id": 1055,
                    "docs_file": "../uploads/1461s444---Elaborato-Planimetrico-with-highlight.pdf",
                    "docs_created_at": "ThuMay14201506: 00: 00GMT+0200(CEST)"
                }
            ]
        },
        {
            "name": "element 2",
            "description": "lorem ipsus",
            "docs": [
                {
                    "docs_id": 1056,
                    "docs_file": "../uploads/pianta.pdf",
                    "docs_created_at": "ThuMay17201106: 00: 00GMT+0200(CEST)"
                },
                {
                    "docs_id": 1055,
                    "docs_file": "../uploads/test.pdf",
                    "docs_created_at": "ThuMay16201706: 00: 00GMT+0200(CEST)"
                }
            ]
        }
    ]
}

このコードを使用して:

apiRoutes.get('/elements', function(req, res) {

var elements = [];  
knex.select().table('element').where(req.query)
    .then (function(rows){
        for(var i in rows){
            var element =  rows[i];
            knex.select().table('document').where('element_id',rows[i].element_id)
                .then (function(docs){
                    element['docs'] = docs;
                    //console.log (elements);
                    elements.push(element);
                });
        }
        res.json (elements);
    });
});

しかし、結果は空の配列です。

クエリの非同期処理の問題かと思いますが解決できません。

4

1 に答える 1

1

for ループが一連の非同期呼び出しを行っています。それらすべてを promise で返す必要があります。bluebirdを使用した例を次に示します。(私はまだこれをテストしていません。)

var Promise = require('bluebird')

knex.select().table('element').where(req.query)
    .then (function(rows){

        var promises = rows.map(function(element){
            return knex.select().table('document').where('element_id',element.element_id)
                .then(function(docs){
                    element['docs'] = docs

                    return element;
                });
        })

       return Promise.all(promises)     
    }).then(function(elements){     
        res.json (elements);
    })
});

ただし、2番目のクエリを発行するのはn+1だと思います。Knex は左外部結合をサポートしています。あなたはそれを使うべきです。

于 2015-11-06T15:23:32.243 に答える