相关疑难解决方法(0)

如何使用新的PostgreSQL JSON数据类型中的字段进行查询?

我正在为PostgreSQL 9.2中的新JSON函数寻找一些文档和/或示例.

具体来说,给定一系列JSON记录:

[
  {name: "Toby", occupation: "Software Engineer"},
  {name: "Zaphod", occupation: "Galactic President"}
]
Run Code Online (Sandbox Code Playgroud)

如何编写SQL以按名称查找记录?

在vanilla SQL中:

SELECT * from json_data WHERE "name" = "Toby"
Run Code Online (Sandbox Code Playgroud)

官方开发手册非常稀少:

更新我

我已经汇总了详细介绍PostgreSQL 9.2目前可能实现的内容.使用一些自定义函数,可以执行以下操作:

SELECT id, json_string(data,'name') FROM things
WHERE json_string(data,'name') LIKE 'G%';
Run Code Online (Sandbox Code Playgroud)

更新II

我现在已将我的JSON函数移动到他们自己的项目中:

PostSQL - 一组用于将PostgreSQL和PL/v8转换为完全令人敬畏的JSON文档存储的函数

sql postgresql json postgresql-9.2 postgresql-9.3

208
推荐指数
3
解决办法
18万
查看次数

查询JSON类型中的数组元素

我正在尝试测试jsonPostgreSQL 9.3中的类型.
我在一个json名为data的表中调用了一列reports.JSON看起来像这样:

{
  "objects": [
    {"src":"foo.png"},
    {"src":"bar.png"}
  ],
  "background":"background.png"
}
Run Code Online (Sandbox Code Playgroud)

我想查询表中所有与'objects'数组中'src'值匹配的报告.例如,是否可以在数据库中查询匹配的所有报告'src' = 'foo.png'?我成功写了一个可以匹配的查询"background":

SELECT data AS data FROM reports where data->>'background' = 'background.png'
Run Code Online (Sandbox Code Playgroud)

但由于"objects"有一系列的价值观,我似乎无法写出有用的东西.是否可以在数据库中查询匹配的所有报告'src' = 'foo.png'?我查看了这些来源,但仍然无法得到它:

我也尝试过这样的事情,但无济于事:

SELECT json_array_elements(data->'objects') AS data from reports
WHERE  data->>'src' = 'foo.png';
Run Code Online (Sandbox Code Playgroud)

我不是SQL专家,所以我不知道我做错了什么.

sql postgresql json lateral jsonb

96
推荐指数
2
解决办法
12万
查看次数

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

我有一个看起来像这样的表:

CREATE TABLE tracks (id SERIAL, artists JSON);

INSERT INTO tracks (id, artists) 
  VALUES (1, '[{"name": "blink-182"}]');

INSERT INTO tracks (id, artists) 
  VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');
Run Code Online (Sandbox Code Playgroud)

还有其他几个与此问题无关的列.将它们存储为JSON是有原因的.

我要做的是查找具有特定艺术家姓名(完全匹配)的曲目.

我正在使用此查询:

SELECT * FROM tracks 
  WHERE 'ARTIST NAME' IN
    (SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)

例如

SELECT * FROM tracks
  WHERE 'The Dirty Heads' IN 
    (SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)

但是,这会进行全表扫描,并且速度不是很快.我尝试使用函数创建GIN索引names_as_array(artists)并使用'ARTIST NAME' = ANY names_as_array(artists),但是不使用索引并且查询实际上明显更慢.

sql postgresql indexing json jsonb

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

带有元素编号的PostgreSQL unnest()

当我有一个具有分隔值的列时,我可以使用该unnest()函数:

myTable
id | elements
---+------------
1  |ab,cd,efg,hi
2  |jk,lm,no,pq
3  |rstuv,wxyz

select id, unnest(string_to_array(elements, ',')) AS elem
from myTable

id | elem
---+-----
1  | ab
1  | cd
1  | efg
1  | hi
2  | jk
...
Run Code Online (Sandbox Code Playgroud)

我如何包含元素编号?即:

id | elem | nr
---+------+---
1  | ab   | 1
1  | cd   | 2
1  | efg  | 3
1  | hi   | 4
2  | jk   | 1
...
Run Code Online (Sandbox Code Playgroud)

我想要源字符串中每个元素的原始位置.我试着窗口函数(row_number(), …

sql arrays postgresql window-functions set-returning-functions

69
推荐指数
3
解决办法
8万
查看次数

Postgres中的GROUP BY - JSON数据类型不相等?

我在匹配表中有以下数据:

5;{"Id":1,"Teams":[{"Name":"TeamA","Players":[{"Name":"AAA"},{"Name":"BBB"}]},{"Name":"TeamB","Players":[{"Name":"CCC"},{"Name":"DDD"}]}],"TeamRank":[1,2]}
6;{"Id":2,"Teams":[{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}]},{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}]}],"TeamRank":[1,2]}
Run Code Online (Sandbox Code Playgroud)

我想按名称选择表格中每个最后一个不同的团队.即我想要一个将返回的查询:

6;{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}
6;{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}
Run Code Online (Sandbox Code Playgroud)

所以每个团队从上次那个团队出现在表中.
我一直在使用以下(从这里):

WITH t AS (SELECT id, json_array_elements(match->'Teams') AS team FROM matches)
SELECT MAX(id) AS max_id, team FROM t GROUP BY team->'Name';
Run Code Online (Sandbox Code Playgroud)

但这回归:

ERROR: could not identify an equality operator for type json
SQL state: 42883
Character: 1680
Run Code Online (Sandbox Code Playgroud)

我知道Postgres 没有JSON的相等性.我只需要团队名称(字符串)的相等性,该团队中的队员不需要进行比较.

任何人都可以建议另一种方法吗?
以供参考:

SELECT id, json_array_elements(match->'Teams') AS team FROM matches
Run Code Online (Sandbox Code Playgroud)

收益:

5;"{"Name":"TeamA","Players":[{"Name":"AAA"},{"Name":"BBB"}]}"
5;"{"Name":"TeamB","Players":[{"Name":"CCC"},{"Name":"DDD"}]}"
6;"{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}]}"
6;"{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}]}"
Run Code Online (Sandbox Code Playgroud)

编辑:我转向text并关注这个问题,我用DISTINCT ON而不是GROUP BY.这是我的完整查询:

WITH t AS (SELECT id, …
Run Code Online (Sandbox Code Playgroud)

sql postgresql json greatest-n-per-group lateral

18
推荐指数
1
解决办法
1万
查看次数

如何查询和索引嵌套在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
查看次数

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
查看次数

Django JSONField并使用ILIKE搜索字典列表

是否可以使用ILIKE(icontains)运算符搜索字典列表中的一个键值?我的json字段看起来像这样:

object = MyModel()
object.json_data = [
    {
        "type": 1,
        "results": [
            {
                "score": 1,
                "comment": "Some text comment 1",
            },
            {
                "score": 2,
                "comment": "Some text comment 2",
            },
            {
                "score": 3,
                "comment": "Some text comment 3",
            }
        ]
    },
    {
        "type": 2,
        "results": [
            {
                "score": 4,
                "comment": "Some text comment 4",
            },
            {
                "score": 5,
                "comment": "Some text comment 5",
            },
            {
                "score": 6,
                "comment": "Some text comment 6",
            }
        ]
    }
]
object.save()
Run Code Online (Sandbox Code Playgroud)

现在,如何编写查询以在"注释"键中搜索?

MyModel.objects.filter(json_data__??__results__??__comment__icontains="text comment") …
Run Code Online (Sandbox Code Playgroud)

django

4
推荐指数
2
解决办法
6160
查看次数

加速 jsonb 对象数组中嵌套的键值的范围测试

假设我有下parents表:

create table parents (
  id       integer not null constraint parents_pkey primary key,
  name     text    not null,
  children jsonb   not null
);
Run Code Online (Sandbox Code Playgroud)

其中children有一个如下结构的json数组:

[
    {
        "name": "child1",
        "age": 10
    }, 
    {
        "name": "child2",
        "age": 12
    } 
]
Run Code Online (Sandbox Code Playgroud)

例如,我需要找到所有有 10 岁到 12 岁孩子的父母。

我创建以下查询:

select distinct
  p.*
from
  parents p, jsonb_array_elements(p.children) c
where
  (c->>'age')::int between 10 and 12;
Run Code Online (Sandbox Code Playgroud)

当表parents很大时(例如 1M 条记录),它工作得很好,但速度很慢。我尝试在children字段上使用“杜松子酒”索引,但这没有帮助。

那么有没有办法加快此类查询的速度呢?或者也许还有另一种解决方案可以对嵌套 json 数组中的字段进行查询/索引?

查询计划

Unique  (cost=1793091.18..1803091.18 …
Run Code Online (Sandbox Code Playgroud)

sql arrays postgresql json jsonb

4
推荐指数
1
解决办法
2124
查看次数