【问题标题】:List all array elements of a MySQL JSON field列出 MySQL JSON 字段的所有数组元素
【发布时间】:2018-01-21 15:45:33
【问题描述】:

我有一个 JSON 字段来保存帖子的标签。

id:1, content:'...', tags: ["tag_1", "tag_2"]

id:2, content:'...', tags: ["tag_3", "tag_2"]

id:3, content:'...', tags: ["tag_1", "tag_2"]

我只想列出所有标签及其流行度(甚至没有它们),如下所示:

tag_2: 3,

tag_1: 2,

tag_3: 1

【问题讨论】:

    标签: mysql arrays json mysql-5.7


    【解决方案1】:

    设置如下:

    create table t ( id serial primary key, content json);
    insert into t set content = '{"tags": ["tag_1", "tag_2"]}';
    insert into t set content = '{"tags": ["tag_3", "tag_2"]}';
    insert into t set content = '{"tags": ["tag_1", "tag_2"]}';
    

    如果您知道任何标签数组中的最大标签数,则可以使用 UNION 提取所有标签:

    select id, json_extract(content, '$.tags[0]') AS tag from t 
    union
    select id, json_extract(content, '$.tags[1]') from t;
    
    +----+---------+
    | id | tag     |
    +----+---------+
    |  1 | "tag_1" |
    |  2 | "tag_3" |
    |  3 | "tag_1" |
    |  1 | "tag_2" |
    |  2 | "tag_2" |
    |  3 | "tag_2" |
    +----+---------+
    

    您需要与最长数组中的标签数量一样多的联合子查询。

    然后你可以把它放在派生表中并对其进行聚合:

    select tag, count(*) as count
    from ( 
        select id, json_extract(content, '$.tags[0]') as tag from t 
        union 
        select id, json_extract(content, '$.tags[1]') from t
    ) as t2
    group by tag
    order by count desc;
    
    +---------+-------+
    | tag     | count |
    +---------+-------+
    | "tag_2" |     3 |
    | "tag_1" |     2 |
    | "tag_3" |     1 |
    +---------+-------+
    

    如果您将标签存储在第二个表中而不是 JSON 数组中,这会更容易:

    create table tags ( id bigint unsigned, tag varchar(20) not null, primary key (id, tag));
    insert into tags set id = 1, tag = 'tag_1';
    insert into tags set id = 1, tag = 'tag_2';
    insert into tags set id = 2, tag = 'tag_3';
    insert into tags set id = 2, tag = 'tag_2';
    insert into tags set id = 3, tag = 'tag_1';
    insert into tags set id = 3, tag = 'tag_2';
    
    select tag, count(*) as count 
    from tags
    group by tag
    order by count desc;
    
    +-------+-------+
    | tag   | count |
    +-------+-------+
    | tag_2 |     3 |
    | tag_1 |     2 |
    | tag_3 |     1 |
    +-------+-------+
    

    无论您的每个 id 有多少标签,此解决方案都有效。您不需要知道每个 id 的标签列表的最大长度。

    当您需要存储半结构化数据的“文档”时,JSON 非常有用,但仅当您将文档视为一个不可约数据值时。一旦您需要访问文档的元素并对它们应用关系操作,面向文档的方法就显示出它的弱点。

    【讨论】:

    • 谢谢!非常有帮助。工作一周!
    猜你喜欢
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多