我使用骨干,需要在类别中的问题和问题中嵌套答案。 我的问题是我从MySQL获得的数据。
我想有一个我可以轻松使用骨干的数组,从顶部开始(类别)并嵌套到底部(答案)。
[Category1: [Question1: [Answer1: {...} ] ] ]
我使用以下查询来获取我的所有MySQL数据:
var getRecord = function(callback) {
var options = {
sql: 'SELECT * FROM Categories ' +
'LEFT JOIN Questions ON Categories.idCategories = Questions.idCategory ' +
'LEFT JOIN Answers ON Questions.idQuestions = Answers.idQuestion ',
nestTables: true
}
req.app.sql.query(options, function(err, result) {
if (err)
return callback(err, null)
outcome.record = result
return callback(null, 'done')
})
}
输出看起来像这样:
[
0: [CategoryObj, QuestionObj, AnswerObj]
1: ...
]
MySQL节点包不会嵌套1:n关系,而是创建一个长度最匹配的数组,所以在这种情况下我有2个类别,每两个问题,每两个答案 - >数组长度为8,因为我总共有8个答案。 但我无法在骨干集合中嵌套这个数组,而无需编写疯狂的循环和黑客。
我在查询中做错了什么,或者是否有解析作业的包?
(我习惯使用MongoDB(使用嵌入式文档非常简单),现在我必须将MySQL用于此项目..)
答案 0 :(得分:2)
包装或使用方式没有任何问题。它只是为您提供MySQL返回的结果。您可能知道,当您处理1:n关系时,MySQL本身不会以“嵌套”方式格式化其结果。如果您使用JOIN,它将为您提供表,其中包含找到的每个结果的行。由于它是“表格式”结果,所有行都具有相同数量的单元格。
例如,您可以尝试在PHPmyAdmin中查看请求的结果。
因此,您必须对结果进行后期格式化。可能有模块可以做到这一点,但我还没有用过。
如果您想自己动手,可以执行以下操作:
var nestedResult = {};
result.forEach(function(val){
var category = val[0],
question = val[1],
answer = val[2];
if (!nestedResult[category]){
nestedResult[category] = {};
}
if (!nestedResult[category][question]){
nestedResult[category][question] = [];
}
nestedResult[category][question].push(answer);
});
这会给你类似的东西:
{
"mysql" : {
"what is JOIN" : ["answer 1 blabla....","answer 2 blabla"],
"innoDB vs MyISAM" : ["answer 1","answer 2"]
},
"php" : {
"why no php 6 ?" : ["answeeeerr"]
}
}
答案 1 :(得分:0)
我最终自己解析了它。出于某种原因,我无法找到一个工作良好的ORM助手,这可以帮我完成这项工作。无论如何,我试图避免这种解决方案,但是如果你有一天遇到同样的问题,那么你就去吧。
var async = require('async')
var getAnswers = function (id, callback) {
req.app.sql.query('SELECT * FROM Answers WHERE idQuestion LIKE ?', [id], function(err, result) {
if (err)
return callback(err, null)
return callback(null, result)
})
}
var getQuestions = function (id, callback) {
req.app.sql.query('SELECT * FROM Questions WHERE idCategory LIKE ?', [id], function(err, result) {
if (err)
return callback(err, null)
// Pair answers to questions
async.times(result.length, function(n, next) {
getAnswers(result[n].idQuestions, function (err, answers) {
result[n].answers = answers
next(err, result[n])
})
}, function(err, questions) {
callback(null, questions)
})
})
}
var getRecord = function(callback) {
req.app.sql.query('SELECT * FROM Categories', function(err, result) {
if (err)
return callback(err, null)
// Pair questions to categories
async.times(result.length, function(n, next) {
getQuestions(result[n].idCategories, function (err, questions) {
result[n].questions = questions
next(err, result[n])
})
}, function(err, final) {
callback(null, final)
})
})
}
var asyncFinally = function(err, results) {
if (err)
return next(err)
// we call results[0] because async.times leaves all the categories in there..
// sendSomewhere( results[0] )
}
async.parallel([getRecord], asyncFinally)