2015-11-06 2 views
0

Я пытаюсь следующий код узла JS с помощью Postgres, чтобы получить список вложенного объекта JSON как это:Node JS - экспресс - Postgres получить вложенные объекты 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); 
    }); 
}); 

, но в результате получается пустой массив.

Я думаю, что это проблема с асинхронной обработкой запросов, но я не могу ее решить.

ответ

1

Ваша петля создает цепочку асинхронных вызовов. Вы должны вернуть все из них в обещание. Вот пример, используя 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); 
    }) 
}); 

Однако, я думаю, что выпуск второго запроса является n+1. Knex поддерживает left outer join. Вы должны использовать это.

+0

РАБОТЫ, Спасибо, Джош !!! Другой вопрос ... Каков наилучший способ, если я обработаю другой подзапрос, например «документ» внутри основного элемента запроса « –

+0

». Я думаю, вы хотите использовать левое внешнее соединение. Это может быть лучше для отдельного вопроса о Stackoveflow. –

Смежные вопросы