在postgres中从json中提取未命名记录的值

时间:2017-03-04 06:38:53

标签: sql arrays json postgresql postgresql-9.3

我的postgres数据库中有json格式的数据,如下所示:

data={"id": "1:2:3", "[{\"info\": \"No\", \"links\": [\"<link rel": "''parent'' href=''http://example.com/1''/>\"], \"uid\": 1}]", "count": "9"}

在这个json数据中,我有三个不同的字段:id< unnamed field >count

我得到了使用此查询提取命名列数据的逻辑:

select data->'count' as count from mydb;

有没有办法从未命名的字段中获取'uid'信息?

1 个答案:

答案 0 :(得分:2)

更新问题后,您提供的JSON有效:

~/.ema

...但它并不代表你的想法。如果您以更易读的方式格式化JSON,它看起来像这样:

{"id": "1:2:3", "[{\"info\": \"No\", \"links\": [\"<link rel": "''parent'' href=''http://example.com/1''/>\"], \"uid\": 1}]", "count": "9"}

因此,请注意,此对象中的第二个条目(根据需要)具有键和值。我将密钥和相应的值放在一个单独的行上以突出显示它。

所以,与你的想法相反 - 以及该字符串中非常具有启发性的东西 - 该键的值不是JSON字符串,而是它的一部分,而它的前半部分用作键,其中(解析了转义字符)是:

{
    "id": "1:2:3", 
    "[{\"info\": \"No\", \"links\": [\"<link rel": 
         "''parent'' href=''http://example.com/1''/>\"], \"uid\": 1}]", 
    "count": "9"
}

所以下面的SQL可以工作:

[{"info": "No", "links": ["<link rel

...并将返回此值:

select mydata->'[{"info": "No", "links": ["<link rel' from mydb

显然这不是您所希望的,但它表明您存储在表中的JSON在语义上是错误的,即使从技术上讲它是有效的JSON。

对象表示始终具有JSON中的键和值。以下是JSON可能更有意义的方法之一:

"'parent' href='http://example.com/1'/>\"], \"uid\": 1}]"

在表中使用此JSON,您可以执行以下SQL:

{
    "id": "1:2:3", 
    "data": [{
        "info": "No", 
        "links": ["<link rel='parent' href='http://example.com/1'/>"],
        "uid": 1
    }], 
    "count": "9"
}

...将输出:

select (mydata->'data'->>0)::json->>'info' from mydb

但是如你所见,JSON看起来很不一样。你不可能说出你提供的信息出了什么问题。当您从正在使用的服务中获取JSON时,应该检查JSON的外观。错误可能已经存在,但更可能是您正在处理此结果,以便在准备将值写入数据库时​​转义字符。可能在那种操作中你打破了JSON的语义。

提供更多信息后

您可以通过URL参数调用服务,如下所示:

No

但是这种在URL中传递参数的方式是不对的,当$('#update').click(function(){ $.post('example.com?data='+ data + '&id='+id + '&count='+count, function callbackHandler(data, textstatus) { // some processing... }, "json" ); }); 包含在URL中具有特殊含义的字符时。您应该使用encodeURIComponent来构建该网址:

data

由于 count 是数字,因此无需对其应用 'example.com?data=' + encodeURIComponent(data) + '&id=' + encodeURIComponent(id) + '&count=' + count ,但如果你这样做则不会造成任何伤害。

这可能会对您从该服务器返回的数据产生积极的影响。