Node JS-express-postgres通过循环查询获取嵌套json个对象
Node JS - express - postgres obtain nested json objects by loop queries
我正在尝试使用 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);
});
});
但结果是一个空数组。
我认为是查询的异步处理有问题,但我无法解决。
您的 for 循环正在进行大量异步调用。您需要 return 承诺所有这些。下面是一个使用 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 supports a left outer join。你应该使用它。
我正在尝试使用 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);
});
});
但结果是一个空数组。
我认为是查询的异步处理有问题,但我无法解决。
您的 for 循环正在进行大量异步调用。您需要 return 承诺所有这些。下面是一个使用 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 supports a left outer join。你应该使用它。