如何检查 Postgres 中是不是存在 json 键?
Posted
技术标签:
【中文标题】如何检查 Postgres 中是不是存在 json 键?【英文标题】:How do I check if a json key exists in Postgres?如何检查 Postgres 中是否存在 json 键? 【发布时间】:2015-03-07 23:35:41 【问题描述】:假设我有一个如下所示的 json:
some_json = 'key_a': 'nested_key': 'a',
'key_b': 'nested_key': 'b'
请注意,key_a
和 key_b
是映射到字典的可选键,可能存在也可能不存在。
我有一个函数可以检查some_json
中是否存在外键并返回一个布尔值。
CREATE FUNCTION key_exists(some_json json, outer_key text)
RETURNS boolean AS $$
BEGIN
RETURN (some_json->outer_key IS NULL);
END;
$$ LANGUAGE plpgsql;
我收到以下错误:
ProgrammingError: operator does not exist: json -> boolean
为什么outer_key
等于布尔值?执行此检查的正确语法是什么?
【问题讨论】:
【参考方案1】:您也可以使用“?”像这样的操作员:
SELECT '"key_a":1'::jsonb ? 'key_a'
如果需要通过嵌套键查询,可以这样使用:
SELECT '"key_a": "nested_key": "a"'::jsonb -> 'key_a' ? 'nested_key'
见http://www.postgresql.org/docs/9.5/static/functions-json.html
注意:仅适用于jsonb
类型。
【讨论】:
请注意,在准备 SQL 语句的服务(例如 Metabase)中使用它时,它不起作用,但您可以使用??
而不是 ?
。
这似乎是一个更好的答案,因为一个值为 null 的键将返回为真,这是预期的。【参考方案2】:
您的函数与名称完全相反,但修复函数的方法是在 some_json->outer_key
周围添加 (
和 )
。
这是功能齐全的,并且与您的函数名称相匹配(注意NULL
前面的NOT
)。
CREATE FUNCTION key_exists(some_json json, outer_key text)
RETURNS boolean AS $$
BEGIN
RETURN (some_json->outer_key) IS NOT NULL;
END;
$$ LANGUAGE plpgsql;
一些测试:
select key_exists('"key_a": "nested_key": "a", "key_b": "nested_key": "b"'::json, 'key_a');
key_exists
------------
t
(1 row)
当密钥不存在时:
select key_exists('"key_a": "nested_key": "a", "key_b": "nested_key": "b"'::json, 'test');
key_exists
------------
f
(1 row)
【讨论】:
搞定了,谢谢!如此简单的修复却很容易被忽视。名字也不错。【参考方案3】:要检查键是否存在,您可以使用操作符 -> 这用于通过键获取 JSON 对象字段 例如:
actual json data in column(attribute):
"active": "t",
"email_address": "kris.ann.augdahl@hp.com",
"pin": "2233"
SELECT attributes::json->'email_address'
FROM entity
WHERE entity_id = 55;
您还可以通过运算符#> 和#>> 搜索关键字
使用操作符 ->>
获取 JSON 对象字段作为文本:'"a":1,"b":2'::json->>'b'【讨论】:
【参考方案4】:在 Postgres 中,如果您选择一个不存在的键,它将返回 null。 因此您可以通过检查该键的空值来检查该键的存在。
select '"key_a": "nested_key": "a",
"key_b": "nested_key": "b"'::jsonb->>'a'
------------
null
(1 row)
【讨论】:
以上是关于如何检查 Postgres 中是不是存在 json 键?的主要内容,如果未能解决你的问题,请参考以下文章