Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Postgres 9.4中查找JSON数组中的最后一项_Json_Postgresql_Postgresql 9.3 - Fatal编程技术网

在Postgres 9.4中查找JSON数组中的最后一项

在Postgres 9.4中查找JSON数组中的最后一项,json,postgresql,postgresql-9.3,Json,Postgresql,Postgresql 9.3,我们有一个遗留系统,它试图跟踪保存在特定文档中的所有版本的数据。我们最初在一些旧版本的Postgres中将JSON存储为字符串,但最近我们升级到了Postgres 9.3,并开始使用JSON列类型 我们有一个名为“versions”的列,其中包含一个数组,每个保存的特定文档版本都存储在该数组中,因此类似这样的查询: SELECT _data_as_json FROM measurements WHERE id = 3307551 返回的JSON如下所示: {"reports": {}, "v

我们有一个遗留系统,它试图跟踪保存在特定文档中的所有版本的数据。我们最初在一些旧版本的Postgres中将JSON存储为字符串,但最近我们升级到了Postgres 9.3,并开始使用JSON列类型

我们有一个名为“versions”的列,其中包含一个数组,每个保存的特定文档版本都存储在该数组中,因此类似这样的查询:

SELECT _data_as_json FROM measurements WHERE id = 3307551
返回的JSON如下所示:

 {"reports": {}, "versions": [
 {"timestamp": "2014-04-28T19:12:31.567415", "user": 11327, "legacy": {}, "vd_version": 1}, 
 {"timestamp": "2014-05-12T18:03:24.417029", "user": 11331, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-05-12T21:52:50.045758", "user": 10373, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-05-14T23:34:37.797822", "user": 10380, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-07-16T14:56:38.667363", "user": 10374, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-07-16T14:57:47.341541", "user": 10374, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-07-17T16:32:09.067026", "user": 11331, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-09-11T14:35:44.436886", "user": 11331, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-10-15T14:30:50.554932", "user": 10383, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-10-29T15:36:35.183787", "user": 11331, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-11-12T22:22:03.892484", "user": 10373, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}
 ]}     
我们(试图)按时间顺序将数据存储在“版本”中,但99%的情况下,我们只需要最后一个文档。在Postgres 9.3中,我们提出了此查询以获取最后一项:

SELECT json_array_elements(_data_as_json->'versions')
FROM measurements
WHERE id = 3307551
LIMIT 1 OFFSET (SELECT json_array_length(_data_as_json->'versions') - 1 FROM measurements WHERE id = 3307551)
这基本上是可行的,但有点脆弱。如果在版本数组中无法正确排序,那么我们将返回错误的文档版本。我很好奇是否有更好的方法?我读到Postgres9.4提供了更多处理JSON的函数

理想情况下,我们可以根据“时间戳”进行订购。可能吗

博士后9.5+ 现在的工作很简单,因为

接受整数JSON的字段/元素/路径提取运算符 数组下标所有支持从数组末尾开始的负下标

我的。所以对于
json
jsonb

SELECT data->'versions'->>-1
FROM   measurements m
WHERE  id = 3307551;
博士后9.4 您可能想使用。相应地使用

一般的方法是根据原始排序顺序,使用具有顺序性的
获取最后一个元素(没有顺序的情况下稍慢):

具有顺序性的
详细信息(以及两个版本中的隐式
连接横向
):

博士后9.3 根据时间戳值的“last”:

SELECT v.ver
FROM   measurements m
     , json_array_elements(m.data->'versions') v(ver)
WHERE  m.id = 3307551
ORDER  BY  (v.ver->>'timestamp')::timestamp DESC
LIMIT  1;
根据
json
数组中的顺序位置选择“last”(最快):

我们需要
-1
,因为JSON数组从偏移量0开始

dbfiddle

Old

您是否可以自由使用Postgres 9.4?今天发布了,耶!除了json(和jsonb)的更多功能外,它还提供了一个非常适合您的新功能:。另外,请定义“最后一个文档”:最后一个是根据数组位置还是根据时间戳值?
SELECT v.ver
FROM   measurements m
     , json_array_elements(m.data->'versions') v(ver)
WHERE  m.id = 3307551
ORDER  BY  (v.ver->>'timestamp')::timestamp DESC
LIMIT  1;
SELECT data->'versions'->(json_array_length(data->'versions') - 1)
FROM   measurements
WHERE  id = 3307551;