当前位置: 首页 > 知识库问答 >
问题:

查询整数成员的jsonb数组

柯默
2023-03-14

背景:我们使用书面记录来记录我们不断变化的模型的历史。现在我想查询一个属于某个客户的项目。PaperTrail可选择存储对象更改,我需要查询此字段以了解何时使用此ID创建了某些内容或更改为此ID。

我的表看起来简化如下:

item_type | object_changes
----------|----------------------------------------------------------
"Item"    | {"customer_id": [null, 5], "other": [null, "change"]}
"Item"    | {"customer_id": [4, 5], "other": ["unrelated", "change"]}
"Item"    | {"customer_id": [5, 6], "other": ["asht", "asht"]}

如何查询从或更改为ID 5的元素(因此上面的所有行)?我试过:

SELECT * FROM versions WHERE object_changes->'customer_id' ? 5;

这让我:

ERROR:  operator does not exist: jsonb ? integer
LINE 1: ...T * FROM versions WHERE object_changes->'customer_id' ? 5;
                                                                 ^
HINT:  No operator matches the given name and argument type(s).
You might need to add explicit type casts.

共有2个答案

胡厉刚
2023-03-14

使用横向联接和jsonb\u array\u elements\u text函数处理每行的对象更改:

SELECT DISTINCT v.* FROM versions v
JOIN LATERAL jsonb_array_elements_text(v.object_changes->'customer_id') ids ON TRUE
WHERE ids.value::int = 5;

只有当您要查找的客户id可能在数组中出现多次时(如果更改了其他字段,但仍跟踪了客户id),才需要使用DISTINCT。

韦德厚
2023-03-14

对于jsonb,contains操作符@

获取数字5是“customer\u id”数组元素的所有行:

SELECT *
FROM   versions 
WHERE  object_changes->'customer_id' @> '5';

<代码>@

  • 没有函数匹配给定的名称和参数类型
  • PostgreSQL错误:函数to_tsvector(字符变化,未知)不存在

不同的索引样式可以支持这一点。对于我上面建议的查询,使用表达式索引(专用、小型和快速):

CREATE INDEX versions_object_changes_customer_id_gin_idx ON versions
USING gin ((object_changes->'customer_id'));

此备选查询也适用:

SELECT * FROM versions WHERE object_changes @> '{"customer_id": [5]}';

并且可以通过通用索引(更通用、更大、更慢)来支持:

CREATE INDEX versions_object_changes_gin_idx ON versions
USING gin (object_changes jsonb_path_ops);

相关:

  • 用于在JSON数组中查找元素的索引

根据手册,操作员搜索JSON值中的任何顶级键。测试表明,数组中的字符串被视为“顶级键”,而数字则不是(键毕竟必须是字符串)。因此,尽管此查询可行:

SELECT * FROM versions WHERE object_changes->'other' ? 'asht';

在数组中查找数字的查询将不会(即使正确引用输入字符串文字)。它只能找到(引用!)分类为键的字符串,但不是分类为值的(无引号)数字。

旁白:标准JSON只知道4个原语:string、number、boolean和null。没有整数原语(即使我听说软件添加了它),整数只是数字的一个子集,在Postgres中实现为数字:

  • https://www.postgresql.org/docs/current/static/datatype-json.html#JSON-TYPE-MAPPING-TABLE

因此,您的问题标题有点误导,因为严格来说,没有“整数”成员。

 类似资料:
  • 问题内容: 我使用 PostgreSQL 9.5 和Rails5。我想查询下面显示的包含JSON对象数组的列,以返回包含并执行计数的所有JSON数组元素。我使用 的 SQL 显示在json数据下方。运行查询只会返回一个空数组。 这是我的数据: 我想要其中一个sql查询返回: 和另一个查询以返回数组,以便我可以在应用程序中对其调用count,还可以遍历它以创建表单: 我试过这个SQL查询: 我也试过

  • 我使用PostgreSQL 9.5和Rails 5。我想查询下面显示的包含JSON对象数组的jsonb列,以返回包含的所有JSON数组元素,并执行计数 我使用的SQL显示在json数据下面。运行查询只返回一个空数组。 我尝试了这里和这里建议的查询。 这就是我的jsonb数据的样子: 我希望其中一个sql查询返回: 和另一个返回数组的查询,以便我可以在我的应用程序中调用count并循环使用它来创建表

  • 问题内容: 我的JSON数据如下所示: 给定文本“ foo”,我想返回所有具有此子字符串的元组。但是我不知道如何编写相同的查询。 我遵循了这个相关的答案,但不知道该怎么做。 这是我现在正在工作的内容: 我不想传递整个文本,而是传递并获得与该文本匹配的结果。 问题答案: 您的解决方案可以进一步简化: 或更简单一点,因为在此示例中,您实际上根本不需要行类型(): dbfiddle 在这里 但这 不是

  • 我有一个密码: 我正在尝试使用toSql()将laravel查询转换为mysql 但我犯了一个错误,比如 对整数调用成员函数toSql() 然后我尝试了 但它返回的输出为'false',我无法得到预期的输出。我不知道为什么会发生这种情况。任何帮助都将不胜感激。 预期产出:

  • 问题内容: 我正在寻找一种使用数组中的“ IN”子句查询postgres jsonb字段的方法。 假设我有一张桌子 我需要选择test_content数组中的label可能为或的行。 我试过了 但是当我想用包含扩展查询时,或者变得复杂… 我需要的是 jsonb运算符可以吗? 问题答案: 简短答案 您可以在横向联接中使用该函数,并在子句中的复杂表达式中使用其结果: 不同 当在单个行中的多个数组元素中

  • 我想尝试拉出只有1个成员的通讯组。我试图编辑一个查询,我用来查找没有成员的组,但没有运气。我一直在寻找解决方案,但一直找不到任何信息。我只是好奇这是否可能。