相关疑难解决方法(0)

jsonb查询与数组中的嵌套对象

我正在使用PostgreSQL 9.4,其中teams包含一个jsonb名为的列的表json.我正在寻找一个查询,我可以让所有拥有球员的球队3,4以及7他们的球员阵容.

该表包含两行,包含以下json数据:

第一排:

{
    "id": 1,
    "name": "foobar",
    "members": {
        "coach": {
            "id": 1,
            "name": "A dude"
        },
        "players": [
            {
                "id": 2,
                "name": "B dude"
            },
            {
                "id": 3,
                "name": "C dude"
            },
            {
                "id": 4,
                "name": "D dude"
            },
            {
                "id": 6,
                "name": "F dude"
            },
            {
                "id": 7,
                "name": "G dude"
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

第二排:

{
    "id": 2,
    "name": "bazbar",
    "members": …
Run Code Online (Sandbox Code Playgroud)

sql postgresql relational-division jsonb postgresql-9.4

9
推荐指数
1
解决办法
4092
查看次数

如何查询和索引嵌套在PostgreSQL 9.3+深层多级的JSON数据?

在PostgreSQL 9.3中,我存储了一些相当复杂的JSON对象,其中数组嵌套在数组中.此片段不是真实数据,但说明了相同的概念:

{
   "customerId" : "12345",
   "orders" : [{
      "orderId" : "54321",
      "lineItems" : [{
         "productId" : "abc",
         "qty" : 3
      }, {
         "productId" : "def",
         "qty" : 1
      }]
   }
}
Run Code Online (Sandbox Code Playgroud)

我希望SQL查询能够对lineItem对象进行操作...不仅在这个单一的JSON结构中,而且在该表列中的所有JSON对象中.例如,一个SQL查询返回所有不同productId的,以及它们的总销售额qty.为了防止这样的查询花了一整天,我可能想要索引lineItem或其子字段.

使用这个StackOverflow问题,我想出了如何编写一个有效的查询:

SELECT
   line_item->>'productId' AS product_id, 
   SUM(CAST(line_item->>'qty' AS INTEGER)) AS qty_sold
FROM
   my_table, 
   json_array_elements(my_table.my_json_column->'orders') AS order,
   json_array_elements(order->'lineItems') AS line_item
GROUP BY product_id;
Run Code Online (Sandbox Code Playgroud)

但是,最初的StackOverflow问题处理的是仅嵌套一层而不是两层的数据.我扩展了相同的概念(即条款中的"横向连接" FROM),通过添加额外的横向连接来深入潜水.但是,我不确定这是否是最佳方法,因此我的问题的第一部分是:查询JSON对象中任意数量级别的 JSON数据的最佳方法是什么?

对于第二部分,在此类嵌套数据上创建索引,此StackOverflow问题再次处理仅嵌套一层深度的数据.然而,我只是完全迷失了,我的头脑游泳试图想想如何将这个应用到更深层次的水平.任何人都可以提供一个明确的方法来索引至少两个级别的数据,lineItems如上所述?

sql postgresql json

8
推荐指数
1
解决办法
4925
查看次数

Postgresql:通过带有索引的通配符和比较运算符在JSON数组中查找值

我有一个表,我想搜索JSON数组数据.

CREATE TABLE data (id SERIAL, json JSON);

INSERT INTO data (id, json) 
  VALUES (1, '[{"name": "Value A", "value": 10}]');

INSERT INTO data (id, json) 
  VALUES (2, '[{"name": "Value B1", "value": 5}, {"name": "Value B2", "value": 15}]');
Run Code Online (Sandbox Code Playgroud)

本回答所述,我创建了一个函数,它还允许在数组数据上创建索引(重要).

CREATE OR REPLACE FUNCTION json_val_arr(_j json, _key text)
  RETURNS text[] AS
$$
SELECT array_agg(elem->>_key)
FROM   json_array_elements(_j) AS x(elem)
$$
  LANGUAGE sql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

如果我想找到一个完整的值(例如"Value B1"),这很好用:

SELECT *
FROM data
WHERE '{"Value B1"}'::text[] <@ (json_val_arr(json, 'name'));
Run Code Online (Sandbox Code Playgroud)

现在我的问题:

  1. 是否可以使用通配符查找值(例如"Value*")?像以下(天真)方法的东西:

    ...
    WHERE '{"Value%"}'::text[] <@ …
    Run Code Online (Sandbox Code Playgroud)

sql postgresql indexing json

8
推荐指数
1
解决办法
7567
查看次数

jsonb和主/外键:在PostgreSQL中表现更好?

我正在考虑将PostgreSQL的jsonb列类型用于新的后端项目,该项目主要用作REST-ful JSON API.我相信PostgreSQL jsonb将非常适合这个项目,因为它将为我提供JSON对象而无需在后端进行转换.

但是,我已经读过,jsonb添加密钥时数据类型会变慢,而我的架构需要使用主键和外键引用.

我想知道是否在自己的列中使用主键/外键(以标准的关系数据库方式),然后jsonb为其余数据创建列将是有益的,否则会导致问题(无论是现在还是未来) ?

简而言之,会:

table car(id int, manufacturer_id int, data jsonb)
Run Code Online (Sandbox Code Playgroud)

表现更好或更差:

table car(data jsonb)
Run Code Online (Sandbox Code Playgroud)

特别是在经常查找外键时?
从性能或架构的角度来看,第一个会有缺点吗?

postgresql database-design foreign-keys jsonb

8
推荐指数
1
解决办法
4773
查看次数

查询包含JSON对象数组的jsonb列

我使用PostgreSQL 9.5和Rails 5.我想查询jsonb下面显示的包含JSON对象数组的列,以返回包含的所有JSON数组元素{"kind":"person"}并执行计数.我使用
SQL显示在json数据下面.运行查询只返回一个空数组.

我已经尝试了这里这里建议的查询.

这就是我的jsonb数据:

   '[
        {"kind":"person", "filter_term":"56","selected_attr":"customer"},
        {"kind":"email", "filter_term":"marketer","selected_attr":"job_title"}
      ]'
Run Code Online (Sandbox Code Playgroud)

我想要一个sql查询返回:

                             data
----------------------------------------------------------------------
 '{"kind":"person", "filter_term":"56","selected_attr":"customer"}'
(1 row)
Run Code Online (Sandbox Code Playgroud)

和另一个返回数组的查询,以便我可以在我的应用程序中调用count并在其上循环以创建表单:

 data
----------------------------------------------------------------------
 '[{"kind":"person", "filter_term":"56","selected_attr":"customer"}]'
 (1 row)
Run Code Online (Sandbox Code Playgroud)

我试过这个SQL查询:

 "SELECT * FROM \"segments\" WHERE (payload @> '[{\"kind\":\"person\"}]')"
Run Code Online (Sandbox Code Playgroud)

我也试过这个查询:

  "SELECT payload FROM segments WHERE payload @> '[{\"kind\":\"person\"}]'::jsonb;"
Run Code Online (Sandbox Code Playgroud)

这是第三个查询:

 "SELECT * FROM segments s WHERE s.payload->'\"#{a}\"' @> '[{\"kind\":\"person\"}]';"
Run Code Online (Sandbox Code Playgroud)

该模型:

class Segment < ApplicationRecord
 store_accessor :payload,:kind, :filter_term, :selected_model_name, :selected_attr, :limit, :selected_operator …
Run Code Online (Sandbox Code Playgroud)

sql postgresql ruby-on-rails rails-activerecord jsonb

7
推荐指数
1
解决办法
4965
查看次数

查询 jsonb 数组的整数成员

背景:我们使用 PaperTrail 来保存我们不断变化的模型的历史。现在我想查询属于某个客户的项目。PaperTrail 可选择存储object_changes,我需要查询此字段以了解何时使用此 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"]}
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM versions WHERE object_changes->'customer_id' ? 5;
Run Code Online (Sandbox Code Playgroud)

这让我:

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 …
Run Code Online (Sandbox Code Playgroud)

postgresql ruby-on-rails paper-trail-gem jsonb postgresql-9.6

7
推荐指数
1
解决办法
2047
查看次数

针对多列的hstore用例

我在决定使用哪种方法时遇到了一些麻烦.

我有几个实体"类型",让我们称它们为A,B和C,它们共享一定数量的属性(大约10-15).我创建了一个名为ENTITIES的表,以及每个常用属性的列.

A,B,C也有一些(大部分)唯一属性(所有布尔值,可以是10到30左右).我不确定在对表建模时遵循的最佳方法是什么:

  1. 在ENTITIES表中为每个属性创建一个列,这意味着不共享该属性的实体类型将只具有空值.
  2. 对每个实体类型的唯一属性使用单独的表,这有点难以管理.
  3. 使用hstore列,每个实体都将在此列中存储其唯一标志.
  4. ???

我倾向于使用3,但我想知道是否有更好的解决方案.

postgresql database-design hstore

6
推荐指数
1
解决办法
2063
查看次数

查询Rails中的Postgres JSON数组字段

我试图在Postgres数据库中查询某个值.我有一个groupsusers表中命名的字段,可以用以下任何一种方式表示:

1.

groups: {"data"=>[{"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}, {"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}]}
Run Code Online (Sandbox Code Playgroud)

2.

groups: [{"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}, {"serie"=>5, "year"=>3, "specialization"=>"Matematica", "management_id"=>1, "group_number"=>2}]
Run Code Online (Sandbox Code Playgroud)

我对这两种表述都很好.但是,我似乎无法找到如何让所有在系列5中的用户让我们说.我尝试了多个查询:

@users = User.where("groups ->> 'data' @>  ?", {serie: 5})
@users = User.where("groups -> 'data' @>  '?'", {serie: 5})
@users = User.where("groups ->> 'data' ->> 'serie' = ?", 5)
Run Code Online (Sandbox Code Playgroud)

还有许多其他尝试,有些比其他尝试更愚蠢(见上文).我该怎么办?

我已经能够确定:

select groups -> 'data' ->> 'serie' from users;  
ERROR: cannot extract field from a non-object.
Run Code Online (Sandbox Code Playgroud)

但是以下查询有效:

select json_array_elements(groups -> 'data') …
Run Code Online (Sandbox Code Playgroud)

arrays postgresql json ruby-on-rails jsonb

6
推荐指数
1
解决办法
4121
查看次数

Query data inside an attribute array in a json column in Postgres 9.6

I have a table say types, which had a JSON column, say location that looks like this:

{ "attribute":[
  {
    "type": "state",
    "value": "CA"
  },
  {
    "type": "distance",
    "value": "200.00"
  } ...
  ]
  } 
Run Code Online (Sandbox Code Playgroud)

Each row in the table has the data, and all have the "type": "state" in it. I want to just extract the value of "type": "state" from every row in the table, and put it in a new column. I checked out several questions on SO, …

sql postgresql json

6
推荐指数
1
解决办法
5735
查看次数

如何在 PostgreSQL 9.4+ 中将简单的 json(b) int 数组转换为整数[]

我有一个来自 json 对象的数组:[1, 9, 12]

由于它使用方括号表示法,因为它是直接从 json 对象获取的,所以我无法将其转换为,::integer[]当我尝试使用时,array_agg(jsonb_array_elements(simpleintarray))我收到一条错误消息,说我需要按 id 进行分组,但由于数组不是对象(键/值) )对,但只是简单的整数,我不知道如何以相当有效的方式实现这一点。

从 json 返回上述简单 int 数组的查询是:

SELECT node.*, elem->'permissions' AS group_node_permissions
    FROM node
    LEFT OUTER JOIN
    jsonb_array_elements(my_user_group.node_permissions) elem
    ON elem->>'id' = node.id::text
    ORDER BY node.id
Run Code Online (Sandbox Code Playgroud)

elem->'permissions'理想情况下应该以 Postgres 数组的形式返回{},以便我稍后可以在其上使用该ANY(intarray)函数。

我想避免做多余的低效解决方法,例如用大括号替换方括号,然后转换elem->'permissions'->>整数数组,将其转换为字符串,尽管这可能会起作用。

在伪代码中,我真正需要的是能够得到相同的结果:

SELECT node.*, elem->'permissions'**::integer[]** AS group_node_permissions,

...但是当然由于json 数组与 PostgreSQL 数组格式之间的[]差异{},这会导致错误。

这是我当前的(非常丑陋的解决方案,但有效):

SELECT node.*, replace(replace(elem->>'permissions', '[', '{'),']','}')::integer[] AS group_node_permissions
Run Code Online (Sandbox Code Playgroud)

它将原始的 (jsonb) 转换为(integer[])[1, 9, …

sql arrays postgresql json types

5
推荐指数
1
解决办法
9002
查看次数