I was looking for index attributes inside a JSONB column but was unable to find this in the documentation.
Asked
Active
Viewed 151 times
1 Answers
1
Yes, this is supported, I am adding an example inline here. But unfortunately, we do not seem to have documented this yet. Could you please open a GitHub issue against us? https://github.com/YugaByte/yugabyte-db
I had installed YB on my machine and used ysqlsh
to connect to it (you can use psql
also) before doing the following.
1. Create a table with a JSONB
column
postgres=# CREATE TABLE orders (
ID serial NOT NULL PRIMARY KEY,
info json NOT NULL
);
CREATE TABLE
Time: 1706.060 ms (00:01.706)
2. Create an index on a JSONB
attribute
postgres=# CREATE INDEX ON orders((info->'items'->>'product'));
CREATE INDEX
Time: 519.093 ms
Describing the table should show the indexes now:
postgres=# \d+ orders;
Table "public.orders"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('orders_id_seq'::regclass) | plain | |
info | json | | not null | | extended | |
Indexes:
"orders_pkey" PRIMARY KEY, lsm (id HASH)
"orders_expr_idx" lsm (((info -> 'items'::text) ->> 'product'::text) HASH)
Notice the presence of the following line which shows the index:
"orders_expr_idx" lsm (((info -> 'items'::text) ->> 'product'::text) HASH)
3. Insert some data
postgres=# INSERT INTO orders (info)
VALUES
('{ "customer": "John Doe", "items": {"product": "Beer" ,"qty": 6}}'),
('{ "customer": "Lily Bush", "items": {"product": "Diaper","qty": 24}}'),
('{ "customer": "Josh William", "items": {"product": "Toy Car","qty": 1}}'),
('{ "customer": "Mary Clark", "items": {"product": "Toy Train","qty": 2}}')
);
4. Query with explain plan
postgres=# EXPLAIN SELECT * from orders WHERE info->'items'->>'product'='Beer';
QUERY PLAN
-------------------------------------------------------------------------------
Index Scan using orders_expr_idx on orders (cost=0.00..4.12 rows=1 width=36)
Index Cond: (((info -> 'items'::text) ->> 'product'::text) = 'Beer'::text)
(2 rows)
Note that per the query plan, this query will use the index to perform the lookup.

Karthik Ranganathan
- 677
- 4
- 9