【问题标题】:How to make nested JSON result from MySQL query in NodeJS?如何从 NodeJS 中的 MySQL 查询中生成嵌套的 JSON 结果?
【发布时间】:2020-09-07 17:06:26
【问题描述】:

我有 2 个 MySQL 表,我们称它为 kj,它是 jj 的父表作为子表。目前,我在我的 NodeJS 代码中编写了 SQL 查询以返回此输出:

[{
    "id_kj": 1,
    "title_kj": "title1",
    "description_kj": "description1",
    "image_kj": "image1",
    "id_jj": 66,
    "title_jj": "title1",
    "description_jj": "description1",
    "image_jj": "image1"
  },
  {
    "id_kj": 1,
    "title_kj": "title1",
    "description_kj": "description1",
    "image_kj": "image1",
    "id_jj": 67,
    "title_jj": "title1",
    "description_jj": "description1",
    "image_jj": "image1"
  },
  {
    "id_kj": 1,
    "title_kj": "title1",
    "description_kj": "description1",
    "image_kj": "image1",
    "id_jj": 68,
    "title_jj": "title1",
    "description_jj": "description1",
    "image_jj": "image1"
  },
  {
    "id_kj": 2,
    "title_kj": "title2",
    "description_kj": "description2",
    "image_kj": "image2",
    "id_jj": 71,
    "title_jj": "title1",
    "description_jj": "description2",
    "image_jj": "image2"
  },
  {
    "id_kj": 2,
    "title_kj": "title2",
    "description_kj": "description2",
    "image_kj": "image2",
    "id_jj": 69,
    "title_jj": "title1",
    "description_jj": "description2",
    "image_jj": "image2"
  },
  {
    "id_kj": 2,
    "title_kj": "title2",
    "description_kj": "description2",
    "image_kj": "image2",
    "id_jj": 70,
    "title_jj": "title1",
    "description_jj": "description2",
    "image_jj": "image2"
  },
  {
    "id_kj": 3,
    "title_kj": "title3",
    "description_kj": "description3",
    "image_kj": "image3",
    "id_jj": 72,
    "title_jj": "title3",
    "description_jj": "description3",
    "image_jj": "image3"
  },
  {
    "id_kj": 3,
    "title_kj": "title3",
    "description_kj": "description3",
    "image_kj": "image3",
    "id_jj": 73,
    "title_jj": "title3",
    "description_jj": "description3",
    "image_jj": "image3"
  },
  {
    "id_kj": 3,
    "title_kj": "title3",
    "description_kj": "description3",
    "image_kj": "image3",
    "id_jj": 74,
    "title_jj": "title3",
    "description_jj": "description3",
    "image_jj": "image3"
  }
]

如何使结果嵌套?我需要id_jj, title_jj, description_jj, image_jj 成为每个id_kj 键的孩子。这是我需要的结果:

[{
    "id_kj": 1,
    "title_kj": "title1",
    "description_kj": "description1",
    "image_kj": "image1",
    "children": [{
        "id_jj": 66,
        "title_jj": "title1",
        "description_jj": "description1",
        "image_jj": "image1"
      },
      {
        "id_jj": 67,
        "title_jj": "title1",
        "description_jj": "description1",
        "image_jj": "image1"
      },
      {
        "id_jj": 68,
        "title_jj": "title1",
        "description_jj": "description1",
        "image_jj": "image1"
      }
    ]
  },
  {
    "id_kj": 2,
    "title_kj": "title2",
    "description_kj": "description2",
    "image_kj": "image2",
    "children": [{
        "id_jj": 71,
        "title_jj": "title1",
        "description_jj": "description2",
        "image_jj": "image2"
      },
      {
        "id_jj": 69,
        "title_jj": "title1",
        "description_jj": "description2",
        "image_jj": "image2"
      },
      {
        "id_jj": 70,
        "title_jj": "title1",
        "description_jj": "description2",
        "image_jj": "image2"
      }
    ]
  },
  {
    "id_kj": 3,
    "title_kj": "title3",
    "description_kj": "description3",
    "image_kj": "image3",
    "children": [{
        "id_jj": 72,
        "title_jj": "title3",
        "description_jj": "description3",
        "image_jj": "image3"
      },
      {
        "id_jj": 73,
        "title_jj": "title3",
        "description_jj": "description3",
        "image_jj": "image3"
      },
      {
        "id_jj": 74,
        "title_jj": "title3",
        "description_jj": "description3",
        "image_jj": "image3"
      }
    ]
  }
]

这是我的代码:

const getData = async function() {
  return new Promise(function(resolve) {
    const query = "SELECT a.`id` AS 'id_kj', a.`title` AS 'title_kj', a.`description` AS 'description_kj', a.`image` AS 'image_kj',\n" +
      "b.`id` AS 'id_jj', b.`title` AS 'title_jj', b.`description` AS 'description_jj', b.`image` AS 'image_jj' FROM `kj` AS a LEFT JOIN `jj` AS b\n" +
      "ON a.`id` = b.`id_kj` GROUP BY a.`id`, b.`id` ORDER BY  a.`title` ASC, b.`title` DESC";
    con.query(query, function(error, results) {
      if (results.length > 0) {
        resolve(results);
      } else {
        resolve(null);
      }
    });
  });
};

module.exports = {
  getNestedData: async function(baseResponse) {
    const data = await getPelatihan();
    return data;
  },
};

我还创建了我的表的 SQL Fiddle 方案,这是小提琴链接: db-fiddle

任何帮助将不胜感激

谢谢

【问题讨论】:

    标签: javascript mysql node.js


    【解决方案1】:

    一个应该非常有效且逻辑上相对简单的选项是在内存中执行连接。

    我们通过连接字段 title_kj 创建 result_kj 表的映射,然后遍历 result_jj 表以填充 result_kj 子级。

    let result_kj = [{ "id_kj": 1, "title_kj": "title2", "description_kj": "description1", "image_kj": "image1", "id_jj": 66, "title_jj": "title2", "description_jj": "description1", "image_jj": "image1" }, { "id_kj": 1, "title_kj": "title2", "description_kj": "description1", "image_kj": "image1", "id_jj": 67, "title_jj": "title2", "description_jj": "description1", "image_jj": "image1" }, { "id_kj": 1, "title_kj": "title1", "description_kj": "description1", "image_kj": "image1", "id_jj": 68, "title_jj": "title1", "description_jj": "description1", "image_jj": "image1" }, { "id_kj": 2, "title_kj": "title2", "description_kj": "description2", "image_kj": "image2", "id_jj": 71, "title_jj": "title1", "description_jj": "description2", "image_jj": "image2" }, { "id_kj": 2, "title_kj": "title2", "description_kj": "description2", "image_kj": "image2", "id_jj": 69, "title_jj": "title1", "description_jj": "description2", "image_jj": "image2" }, { "id_kj": 2, "title_kj": "title2", "description_kj": "description2", "image_kj": "image2", "id_jj": 70, "title_jj": "title1", "description_jj": "description2", "image_jj": "image2" }, { "id_kj": 3, "title_kj": "title3", "description_kj": "description3", "image_kj": "image3", "id_jj": 72, "title_jj": "title3", "description_jj": "description3", "image_jj": "image3" }, { "id_kj": 3, "title_kj": "title3", "description_kj": "description3", "image_kj": "image3", "id_jj": 73, "title_jj": "title3", "description_jj": "description3", "image_jj": "image3" }, { "id_kj": 3, "title_kj": "title3", "description_kj": "description3", "image_kj": "image3", "id_jj": 74, "title_jj": "title3", "description_jj": "description3", "image_jj": "image3" } ]; 
    let result_jj = [{ "id_jj": 66, "title_jj": "title1", "description_jj": "description1", "image_jj": "image1" }, { "id_jj": 67, "title_jj": "title1", "description_jj": "description1", "image_jj": "image1" }, { "id_jj": 68, "title_jj": "title1", "description_jj": "description1", "image_jj": "image1" }, { "id_jj": 71, "title_jj": "title2", "description_jj": "description2", "image_jj": "image2" }, { "id_jj": 69, "title_jj": "title2", "description_jj": "description2", "image_jj": "image2" }, { "id_jj": 70, "title_jj": "title2", "description_jj": "description2", "image_jj": "image2" }, { "id_jj": 72, "title_jj": "title3", "description_jj": "description3", "image_jj": "image3" }, { "id_jj": 73, "title_jj": "title3", "description_jj": "description3", "image_jj": "image3" }, { "id_jj": 74, "title_jj": "title3", "description_jj": "description3", "image_jj": "image3" } ]; 
       
    // Sort by the relevant key
    const sortKey = "title_kj";
    result_kj.sort((a, b) => {
        if (a[sortKey] < b[sortKey]) {
            return -1;
        }
        if (a[sortKey] > b[sortKey]) {
            return 1;
        }
        return 0;
    })
    
    let kjMap = result_kj.reduce((map, row) => {
        key = row["title_kj"]; 
        map[key] = row;
        return map;
    }, {})
    
    let resultMap = result_jj.reduce((map, row) => { 
        let key = row["title_jj"];
        if (map[key]) { 
            if (!map[key].children) map[key].children = [];
            map[key].children.push(row);
        }
        return map;
    }, kjMap)
    
    let result = Object.values(resultMap);
    console.log("Result:", result);

    【讨论】:

    • 您好,感谢您的回答。如果我错了,请纠正我,为了生成 result_kj 和 result_jj 我需要 2 个查询?
    • 嗨@MANsyori,你绝对做到了!但是,这 2 个查询可能比 1 个复杂的连接查询占用更少的资源。在任何情况下都不会有很大的不同。
    • 哇,它有效!谢谢。如果你不介意,我还有一个问题。如何安排父结果按字母顺序排序? jj 结果映射已按原样排序。在父查询中使用 ORDER BY title ASC 不起作用。
    • 如果我们愿意,我们可以在内存中进行排序,尽管它也应该在 SQL 领域中工作。为了完整起见,我将添加一个在内存中排序的示例!
    • parent没有排序的原因是我把parent中的“key”改成id_kj,把children的“key”改成id_kj,默认排序是基于@ 987654328@。在这种情况下,我最终添加了一个新功能并按照您所说的在内存中排序,现在一切都完成了!再次感谢。干杯。
    猜你喜欢
    • 2019-05-05
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    相关资源
    最近更新 更多