MySQL with Node:如何返回嵌套数据
Posted
技术标签:
【中文标题】MySQL with Node:如何返回嵌套数据【英文标题】:MySQL with Node: how to return nested data 【发布时间】:2020-05-19 20:57:23 【问题描述】:我有三个表:post、tag 和 post_tag。
CREATE TABLE post (
id INT NOT NULL,
title VARCHAR(45) NULL,
PRIMARY KEY (id));
CREATE TABLE tag (
id INT NOT NULL,
tag VARCHAR(45) NULL,
PRIMARY KEY (id));
CREATE TABLE post_tag (
post_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (post_id, tag_id),
INDEX fk_post_tag_tag1_idx (tag_id ASC),
INDEX fk_post_tag_post_idx (post_id ASC),
CONSTRAINT fk_post_tag_post
FOREIGN KEY (post_id)
REFERENCES post (id),
CONSTRAINT fk_post_tag_tag1
FOREIGN KEY (tag_id)
REFERENCES tag (id));
INSERT INTO post (id, title) VALUES (1, 'post 1');
INSERT INTO post (id, title) VALUES (2, 'post 2');
INSERT INTO tag (id, tag) VALUES (1, 'tag 1');
INSERT INTO tag (id, tag) VALUES (2, 'tag 2');
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 1);
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 2);
INSERT INTO post_tag (post_id, tag_id) VALUES (2, 1);
INSERT INTO post_tag (post_id, tag_id) VALUES (2, 2);
然后我可以创建一个存储过程来检索带有标签的第一篇文章:
DELIMITER $$
CREATE PROCEDURE select_posts_tags(IN id INT)
BEGIN
SELECT *
FROM post
INNER JOIN post_tag pt ON post.id = pt.post_id
INNER JOIN tag t ON t.id = pt.tag_id
WHERE post.id = id
GROUP BY post.id, t.id;
END $$
DELIMITER ;
最后我从 Node 调用存储过程:
var mysql = require("mysql");
var connection = mysql.createConnection(
host: "127.0.0.1",
user: "test_database",
password: "test_database",
database: "test_database",
);
connection.connect();
const sql = `CALL select_posts_tags($1)`;
connection.query(sql, (error, results) =>
console.log(JSON.stringify(results[0], null, 4))
);
connection.end();
但结果是一个平面对象数组:
[
"id": 1,
"title": "post 1",
"post_id": 1,
"tag_id": 1,
"tag": "tag 1"
,
"id": 2,
"title": "post 1",
"post_id": 1,
"tag_id": 2,
"tag": "tag 2"
]
结果是一个相同的平面 JSON 对象的数组,用不同的标签重复了两次;
如何将标签作为嵌套数组检索到帖子对象内的 «tags» 键中?结果应该是这样的:
[
id: 1,
title: "post 1",
tags: [
id: 1,
tag: "tag 1",
,
id: 2,
tag: "tag 2",
,
],
,
];
谢谢!
【问题讨论】:
【参考方案1】:您可以使用json_arrayagg()
和json_object()
,如下所示:
SELECT
p.id,
p.title,
json_arrayagg(json_object('id', t.id, 'tag', t.tag)) tags
FROM post p
INNER JOIN post_tag pt ON p.id = pt.post_id
INNER JOIN tag t ON t.id = pt.tag_id
WHERE p.id = ?
GROUP BY p.id, p.title;
【讨论】:
谢谢,有道理……但我在标签数组中转义了 JSON:"[\"id\": 1, \"tag\": \"tag 1\", \"id\": 2, \"tag\": \"tag 2\"]"
。有没有办法避免这种情况?
以字符串形式返回的嵌套 JSON 的错误是由于使用了 npm mysql
包而不是 mysql2
以上是关于MySQL with Node:如何返回嵌套数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在单个查询中返回 node.js mysql 中的嵌套 json
如何使用 Mysql Joins 而不是嵌套子查询来实现相同的结果?