标签: json

在 Postgres 中搜索 JSON 数据哪个更有效:GIN 或多个索引列?

例如,假设我有一个中等行数(约 100,000 行)的表,其中一jsonb列包含以下示例数据:

{"name":"Bob", "favoriteColor":"red", "someOtherObject": {"somethingElse": true}}
Run Code Online (Sandbox Code Playgroud)

是否更有效:

  1. 在 jsonb 列上使用 GIN 索引,然后使用 Postgres 的内置 JSON 查询函数来提取数据

  2. 创建多列来表示可以搜索的内容,即一列用于name,一列用于favoriteColor等;在这些列上构建 b 树索引,然后运行select document from table where name = 'Bob'

  3. 一些其他的解决方案?

    请记住,解决方案需要有效地支持like查询,以便能够搜索以给定输入字符串开头的值。

postgresql index json postgresql-9.6

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

PostgreSQL,在数字 JSON 数组中按值查找元素

我有一个表定义为:

create table dummy (jdata jsonb);
Run Code Online (Sandbox Code Playgroud)

我插入了以下两行:

insert into dummy values ('["dog","cat","elephant","waffle"]');
insert into dummy values ('[1,2,3,4]');
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用 jsonb?&运算符,它可以让您提出问题“所有这些键/元素字符串都存在吗?”

使用字符串字段的示例有效:

select * from dummy where jdata ?& array['cat','dog'];
            jdata                 
--------------------------------------
["dog", "cat", "elephant", "waffle"]
(1 row)
Run Code Online (Sandbox Code Playgroud)

但是,尝试使用包含数字的数组来执行此操作是行不通的:

select * from dummy where jdata ?& array['1','2'];
  jdata 
  -------
(0 rows)

select * from dummy where jdata ?& array['1','2'];
 jdata 
 -------
 (0 rows)

select * from dummy where jdata ?& array[1,2];
ERROR:  operator does not exist: jsonb ?& integer[]
LINE …
Run Code Online (Sandbox Code Playgroud)

postgresql array json

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

PostgreSQL 运算符使用索引但底层函数不使用

我正在尝试JSONB与 JDBC一起使用,这意味着我必须避免使用任何使用 '?' 的运算符。字符(因为 PostgreSQL JDBC 驱动程序没有对该字符进行转义)。拿一个简单的表格:

CREATE TABLE jsonthings(d JSONB NOT NULL);
INSERT INTO jsonthings VALUES
    ('{"name":"First","tags":["foo"]}')
  , ('{"name":"Second","tags":["foo","bar"]}')
  , ('{"name":"Third","tags":["bar","baz"]}')
  , ('{"name":"Fourth","tags":["baz"]}');
CREATE INDEX idx_jsonthings_name ON jsonthings USING GIN ((d->'name'));
Run Code Online (Sandbox Code Playgroud)

使用命令行我可以运行一个简单的选择并按预期使用索引:

EXPLAIN ANALYZE SELECT d FROM jsonthings WHERE d->'name' ? 'First';

                                                            QUERY PLAN                                                            
----------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on jsonthings  (cost=113.50..30236.13 rows=10000 width=61) (actual time=0.024..0.025 rows=1 loops=1)
   Recheck Cond: ((d -> 'name'::text) ? 'First'::text)
   Heap Blocks: exact=1
   ->  Bitmap Index Scan on idx_jsonthings_name  (cost=0.00..111.00 rows=10000 width=0) (actual …
Run Code Online (Sandbox Code Playgroud)

postgresql index-tuning json operator postgresql-9.4

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

Postgres 9.4+:JSONB 而不是 EAV

我正在想办法构建一个新的 PostgreSQL 数据库,我很好奇是否可以使用 JSONB 列而不是 EAV 模型来存储实体的属性。这似乎是一种灵活的方式来存储这些东西。

在 EAV 情况下,我将有 3 个表:

materials (mat_id, mat_name, mat_descr)
material_properties (prop_id, prop_name, prop_desc)
material_property_values (mat_id, prop_id, val)
Run Code Online (Sandbox Code Playgroud)

每种材料都可以有一组不同的属性。

有什么原因我不应该只mat_props JSONB在我的materials表中添加一列,并将所有属性存储在那里{"name":"value"}?这样,将属性作为列进行查询将非常简单:

SELECT mat_name, mat_props->'name' as propval FROM materials
Run Code Online (Sandbox Code Playgroud)

而不是连接或子选择。

另外,我是否可以在materials表中添加此列,或者将其保存在单独的表中是否会更高效:

material_properties (mat_id, properties JSONB)
Run Code Online (Sandbox Code Playgroud)

postgresql database-design eav json

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

具有动态键的 JSON 字段索引

我使用的是 PG 9.5,我有一个表 Visitor(id, data::json)

例子:

Visitor(id: 1, data: {name: 'Jack', age: 33, is_user: true })
Run Code Online (Sandbox Code Playgroud)

我想执行类似的查询

  • 给我所有姓名为 Jack 且年龄 > 25 的访客
  • 给我所有是用户但名称未指定的访问者(密钥不在 json 中)

数据列内的键是用户指定的,因此是动态的。

在这种情况下哪个索引最有意义?

postgresql index json postgresql-9.5

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

从 JSON 对象数组中提取 JSON 数字数组

我有一个包含类似于此对象的 json 数组的表:

id    |   record
____________________
name1 | [{"a":0, "b":x}, {"a":1, "b":y}, {"a":2, "b":z}, ...]
Run Code Online (Sandbox Code Playgroud)

我想得到一个包含仅包含“a”值的 json 数组的表:

id    |   record
____________________
name1 | [0, 1, 2, ...]
Run Code Online (Sandbox Code Playgroud)

我使用的是 PostgreSQL 11,所以最新的功能是可以接受的。

postgresql array json

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

如何控制 JSON_ARRAYAGG 如何对结果进行排序

我正在测试 MySQLJSON_ARRAYJSON_ARRAYAGG函数,以便将一些应用程序昂贵的进程移动到 SQL 存储函数。

在下面的电子商务应用程序示例中,我尝试检索用户的购物车,而不是作为来自 cart_items 表的行结果集,而是作为包含 Javascript 回调函数呈现购物车所需的所有信息的 JSON 字符串。

我有一张cart包含一般购物车信息的表格

create table user_cart (
  cart_id  integer unsigned primary key,
  user_id  integer unsigned not null,
);
Run Code Online (Sandbox Code Playgroud)

cart_item明细表,

create table cart_item (
  cart_item_id  integer unsigned primary key auto_increment,
  cart_id       integer unsigned not null,
  product_id    integer unsigned not null,

  qty           integer unsigned not null,
  ref           varchar(15) not null,

  -- total
  base          double default 0.0,
  tax           double default 0.0,
  tax_pct       double default 0.0,
  total …
Run Code Online (Sandbox Code Playgroud)

mysql json

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

在 json/jsonb 行上使用 IS DISTINCT FROM 触发而不进行比较逐项?

当表具有 json 或 jsonb 列时,是否无法在 INSERT/UPDATE 触发器中进行全行比较?我收到的错误让我认为我需要单独比较每一列,因为该NEW.*/OLD.*格式不能用于比较 json 列。

CREATE OR REPLACE FUNCTION on_insert_update_modified()
RETURNS TRIGGER AS $$
BEGIN
  IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
    NEW.modified_at = now();
    RETURN NEW;
  ELSE
    RETURN OLD;
  END IF;
END;
$$ language 'plpgsql';

CREATE TRIGGER mytable_insert_update
BEFORE INSERT OR UPDATE ON mytable
FOR EACH ROW
EXECUTE PROCEDURE on_insert_update_modified();
Run Code Online (Sandbox Code Playgroud)

当我插入包含 json 和 jsonb 列的表时,出现以下错误:

CREATE OR REPLACE FUNCTION on_insert_update_modified()
RETURNS TRIGGER AS $$
BEGIN
  IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
    NEW.modified_at …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger plpgsql json postgresql-9.6

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

为什么 SQL Server 将它的 (JSON) 响应拆分为多行?

我正在尝试构建一个查询,该查询会生成一个由 SQL Server 生成的 JSON 对象。我发现我可以使用子查询用包含问题列表的 JSON 字符串填充字段(在本例中为问题字段)。

下面是查询:

SELECT
    quizzes.id AS 'id',
    quizzes.name AS 'name',
    quizzes.description AS 'description',
    quizzes.instructions AS 'instructions',
    author.id AS 'author.id',
    author.midas AS 'author.midas',
    author.first_name AS 'author.first_name',
    author.last_name AS 'author.last_name',
    author.email AS 'author.email',
    author.tel AS 'author.tel',
    author.department_name AS 'author.department_name',
    author.created_at AS 'author.created_at',
    author.last_updated AS 'author.last_updated',
    course.id AS 'course.id',
    course.name AS 'course.name',
    course.description AS 'course.description',
    course.crn AS 'course.crn',
    instructor.id AS 'course.instructor.id',
    instructor.midas AS 'course.instructor.midas',
    instructor.first_name AS 'course.instructor.first_name',
    instructor.last_name AS 'course.instructor.last_name',
    instructor.email AS 'course.instructor.email',
    instructor.tel AS 'course.instructor.tel',
    instructor.department_name …
Run Code Online (Sandbox Code Playgroud)

sql-server query subquery json

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

Postgresql:修改嵌套 json 列内的一个值

我在“资产”表中有一个名为“参数”的 json 列。json 是嵌套的并具有以下结构:

{
"params1": {"k": 1.1, "efficiency": 0.7}, 
"params2": {"k": 1.9, "C_max": 100.0, "C_min": 10.0}
}
Run Code Online (Sandbox Code Playgroud)

我只想更新“params2”中的一个值“k”,并保持其余值不变。我尝试使用以下代码:

update "Assets" 
set "Parameters" = "Parameters"::jsonb || '{"params2":{"k":2.2}}'::jsonb
where "Id" = 185;
Run Code Online (Sandbox Code Playgroud)

这导致

{
"params1": {"k": 1.1, "efficiency": 0.7}, 
"params2": {"k": 2.2}
}
Run Code Online (Sandbox Code Playgroud)

因此“params2”中的其余参数被删除,这是不希望的。修改“k”并保持其余部分不变的方法是什么?

postgresql json

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