我有一个简单的查询来检查jsonb对象中是否存在密钥
SELECT data->$1 jdata FROM "my-scheme"."my-table"
我使用此查询遇到了2个问题:
1)如果我将'foo'
作为$1
传递但"'foo'"
和"'foo'->'bar'"
失败,则效果正常。所以我不知道如何达到深钥匙。我使用node-postgres
2)我只想检查密钥是否存在,而不是通过该密钥获取所有数据。
所以问题是:如何检查密钥是否存在于jsonb对象内部,而不是通过该密钥获取所有数据?
答案 0 :(得分:7)
您可以使用#>
运算符在特定路径(指定为键数组)中提取元素。
您还可以通过?
运算符检查顶层是否存在密钥,但似乎没有任何接受路径的变体。
所以其中任何一个都会这样做:
SELECT '{"a":{"b":{"c":1}}}'::jsonb #> '{a,b}' ? 'c'
SELECT '{"a":{"b":{"c":1}}}'::jsonb #> '{a,b,c}' IS NOT NULL
第二个可能更高效,因为它可以避免在将运算符链接在一起时构造中间jsonb
值。
答案 1 :(得分:1)
for (int i = 1; i <= 50; i++)
{
if (getOrdersCall.Pagination != null && i > getOrdersCall.PaginationResult.TotalNumberOfPages)
break;
getOrdersCall.Pagination = new PaginationType() { PageNumber = i, PageNumberSpecified = true, EntriesPerPage = 50, EntriesPerPageSpecified = true };
getOrdersCall.OrderRole = TradingRoleCodeType.Seller;
getOrdersCall.OrderStatus = OrderStatusCodeType.All;
if (String.IsNullOrEmpty(Settings.OrderStatus))
{
getOrdersCall.CreateTimeFrom = Settings.LastDownloadUtc;
getOrdersCall.CreateTimeTo = Settings.LastDownloadUtcEnd;
}
else
{
getOrdersCall.ModTimeFrom = Settings.LastDownloadUtc;
getOrdersCall.ModTimeTo = Settings.LastDownloadUtcEnd;
}
getOrdersCall.Execute();
GetOrdersResponseType response = getOrdersCall.AbstractResponse as GetOrdersResponseType;
if (response.Ack == AckCodeType.Success)
{
orders.AddRange(response.OrderArray);
}
}
是有效的json。
{
"a": {
"b": 5
}
}
无效json。在指定json字符串时使用双引号(在键周围),在将它们写为postgres标识符时使用单引号。
反正:
{
'a': {
'b': 5
}
}
更多嵌套:
SELECT distinct true AS found FROM table_name WHERE column_name -> 'foo' ? 'bar';
如果找到密钥,将返回1条记录;如果未找到密钥,则返回0条记录。如果你不想指定路径,那么我认为最好的方法是编写一个函数/存储过程来遍历所有的键。
您正在寻找的运营商是什么?
摘自:http://www.postgresql.org/docs/9.5/static/functions-json.html
SELECT distinct true AS found FROM jtest WHERE js -> 'a' -> 'c' ? 'd';