【问题标题】:MySQL Nesting RelationsMySQL 嵌套关系
【发布时间】:2014-08-14 08:57:04
【问题描述】:

我使用主干,需要在问题和类别中嵌套问题的答案。 我的问题是我从 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..)

这是MySQL Node Package on npm

【问题讨论】:

  • 请附上json编码的输出
  • @Evgeniy json 编码输出是什么意思?第三个例子正是我得到的。

标签: mysql node.js backbone.js express node-mysql


【解决方案1】:

包装或使用方式没有任何问题。它只是为您提供MySQL 返回的结果。您可能知道,当您处理 1:n 关系时,MySQL 本身不会以“嵌套”方式格式化其结果。如果您使用 JOIN,它会为您提供一个 table,其中每个找到的结果对应一行。由于它是“表格格式”的结果,所有行都有相同数量的单元格

例如,您可以尝试在 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"]
  }
}

【讨论】:

  • 感谢您的回答,我花了最后几个小时编写解析器。无论如何,我最终自己解析/嵌套它。我试图避免这种方式,但没有其他简单的方法。
【解决方案2】:

我最终自己解析了它。出于某种原因,我找不到可以为我完成这项工作的工作良好的 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)

【讨论】:

    猜你喜欢
    • 2013-05-27
    • 2014-10-27
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2021-07-19
    相关资源
    最近更新 更多