在PostgreSQL表中存档可以访问API的大型JSON对象的正确方法是什么?

时间:2016-07-18 20:12:23

标签: postgresql

我现在已经解决了这个问题。我在统计网站上工作是我玩游戏的爱好。

基本上我有一个脚本每5分钟访问游戏的API(可能会增加到15分钟)并立即拉出所有比赛的当前状态。我最初将此对象存储为表格中的JSON列。 (然后每行在JSON列中有一个118kb的对象)

问题是尝试查询表以获取整个存档一周时间(这是匹配的持续时间)。基本上,当我想要的只是JSON中的特定密钥时,它正在拉动2016年118kb记录进行为期一周的比赛。对此API端点的请求大约需要10秒钟才能完成!

我只在PostgreSQL中找到了基于JSON密钥查询行的方法,但没有办法像SELECT match.kills FROM matches WHERE...这样做。

我已经意识到这不起作用所以我想尝试从JSON对象中获取密钥并将它们插入到相应的表列中。

JSON对象框架如下所示:

{
  id: string,
  start_time: timestamp,
  end_time: timestamp,
  scores: {
    green: number,
    blue: number,
    red: number 
  },
  worlds: number[],
  all_worlds: number[][],
  deaths: {
    green: number,
    blue: number,
    red: number
  },
  kills: {
    green: number,
    blue: number,
    red: number
  },
  maps: [
    {
      id: number,
      type: string,
      scores: same as above,
      bonuses: {
        type: string,
        owner: string
      },
      deaths: same as above,
      kills: same as above,
      objectives: [
        {
          id: string,
          type: string,
          owner: string,
          last_flipped: timestamp,
          claimed_by: guild id (put this into another api endpoint),
          claimed_at: timestamp
        },
        ... (repeat 17 times)
      ]
    },
    ... (repeat 3 times)
  ]
}

所以我想将这个键存储在我的数据库中作为列,但是我不太清楚如何为类型为object的键创建它。

最终目标是以一种我可以通过URL访问API的方式存储它,例如:

mywebsite.com/api/v1/matcharchive?data=kills,deaths,score&matchid=1-1&archive_time=2016-07-09T02:00:00Z

它将只在数据库中查询对象中的那3个键并返回它们。

将具有这么多密钥的JSON对象存储到PSQL表中的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

您只需要在json字段上使用->运算符。此示例稍作编辑,因此自动增量键稍微关闭。

host=# create table tmp1 ( id serial primary key, data json);
CREATE TABLE
host=# \d tmp1
                         Table "public.tmp1"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('tmp1_id_seq'::regclass)
 data   | json    | 
Indexes:
    "tmp1_pkey" PRIMARY KEY, btree (id)

host=# insert into tmp1 (data) values ('{"a":1, "b":2}'), ('{"a":3, "b":4}'), ('{"a":5, "c":6}');
INSERT 0 3
host=# select * from tmp1;
 id |      data      
----+----------------
  2 | {"a":1, "b":2}
  3 | {"a":3, "b":4}
  4 | {"a":5, "c":6}
(3 rows)   

host=# select id, data->'b' from tmp1;
 id | ?column?
----+----------
  2 | 2
  3 | 4
  4 |
(3 rows)