sql - 在 PostgreSQL 中使用 json 数组中的索引

标签 sql arrays postgresql indexing jsonb

引用original stackoverflow question ,我正在尝试将 gin 索引应用于 Postgres 9.4 中数组对象中的键,但我没有得到第一个答案中所述的结果。

你能纠正错误吗?

我遵循的步骤已写在下面。

第 1 部分:创建表和索引

CREATE TABLE tracks (id serial, artists jsonb);
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]');
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');

第 2 部分:查询

SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
 id | artists 
----+---------
(0 rows)

此查询给出空结果。
我还尝试使用 jsonb_path_ops GIN 索引。

替代索引和查询:

DROP INDEX tracks_artists_gin_idx;
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING  gin (artists jsonb_path_ops);
SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
 id | artists 
----+---------
(0 rows)

最佳答案

这个来自 original answer 的特定 jsonb 示例缺少包含查询的非原始对象周围的数组层 []。它已被修复。

为 PostgreSQL 9.4.x 记录的行为 jsonb Containment and Existence状态:

The general principle is that the contained object must match the containing object as to structure and data contents

...

As a special exception to the general principle that the structures must match, an array may contain a primitive value

特殊异常允许我们执行以下操作:

CREATE TABLE tracks (id serial, artistnames jsonb);
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artistnames);
INSERT INTO tracks (id, artists) VALUES (1, '["blink-182"]');
INSERT INTO tracks (id, artists) VALUES (2, '["The Dirty Heads", "Louis Richards"]');

我们可以使用一般原则查询包含:

SELECT * FROM tracks WHERE artistnames @> '["The Dirty Heads"]';
 id |              artistnames              
----+---------------------------------------
  2 | ["The Dirty Heads", "Louis Richards"]
(1 row)

我们还可以使用特殊异常查询包含,因为数组包含基本类型:

SELECT * FROM tracks WHERE artistnames @> '"The Dirty Heads"';
 id |              artistnames              
----+---------------------------------------
  2 | ["The Dirty Heads", "Louis Richards"]
(1 row)

有 4 种基本类型允许对数组进行包含和存在查询:

  1. 字符串
  2. 人数
  3. bool 值

由于您在问题中提到的示例是处理嵌套在数组中的对象,因此我们不符合上述特殊异常(exception)的条件:

CREATE TABLE tracks (id serial, artists jsonb);
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]');
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');

我们可以使用一般原则查询包含:

SELECT * FROM tracks WHERE artists @> '[{"name": "The Dirty Heads"}]';
 id |                          artists                          
----+-----------------------------------------------------------
  2 | [{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]
(1 row)

对象不被视为原始类型,因此以下包含查询不符合特殊异常的条件,因此不起作用:

SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
 id | artists 
----+---------
(0 rows)

关于sql - 在 PostgreSQL 中使用 json 数组中的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29945205/

相关文章:

java - 如何在 React 应用程序中使用 Java 并使用 MySQL 作为数据库。有什么建议吗?

python - 如何从 Python 中的数组中获取第一个、第三个和第五个元素?

postgresql - postgres中的月份(仅月份)的数据类型是什么?

sql - 在 postgresql 中使用 meteor

python - 如何避免在 Postgresql 的 INSERT 期间显式转换 NULL

sql - 增量 SQL 查询

sql - SQL-SSMS2005-如何将数据库图复制到另一个数据库?

sql - 插入后使用触发器更新多行(sql server)

c++ - 内联数组初始化

arrays - 如何使用 JSON 发送带有数组的字典?