Search code examples
postgresqlhstorejsonb

Migrate flat jsonb to hstore


I run postgres 9.4, and want to migrate column in my database table to hstore just to be able to make performance comparison.

My current column is key-value pair in jsonb, w/o nested structure.

Any tips how to approach this problem?


Solution

  • Example data:

    create table jsons (id int, val jsonb);
    insert into jsons values
    (1, '{"age":22}'), 
    (2, '{"height":182}'),
    (3, '{"age":30, "height":177}');
    

    Split json objects to key, value pairs:

        select id, (jsonb_each_text(val)).key, (jsonb_each_text(val)).value
        from jsons
    
     id |  key   | value 
    ----+--------+-------
      1 | age    | 22
      2 | height | 182
      3 | age    | 30
      3 | height | 177
    (4 rows)        
    

    Aggregate the pairs and convert them to hstore:

    select id, hstore(array_agg(key), array_agg(value))
    from (
        select id, (jsonb_each_text(val)).key, (jsonb_each_text(val)).value
        from jsons
        ) sub
    group by 1
    order by 1
    
     id |            hstore            
    ----+------------------------------
      1 | "age"=>"22"
      2 | "height"=>"182"
      3 | "age"=>"30", "height"=>"177"
    (3 rows)    
    

    The same can be accomplished in a more elegant way using lateral join:

    select id, hstore(array_agg(key), array_agg(value))
    from jsons
    cross join jsonb_each_text(val)
    group by 1
    order by 1;