By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE TABLE
INSERT 0 2
CREATE INDEX
id | experience |
---|---|
1 | [{"field": "devops", "years": 9}, {"field": "backend dev", "years": 7}] |
SELECT 1
id | experience |
---|---|
1 | [{"field": "devops", "years": 9}, {"field": "backend dev", "years": 7}] |
SELECT 1
SET
QUERY PLAN |
---|
Limit (cost=10000000000.00..10000000001.03 rows=1 width=36) |
-> Seq Scan on users (cost=10000000000.00..10000000001.03 rows=1 width=36) |
Filter: (jsonb_path_exists(experience, '$[*]?(@."field" == "devops" && @."years" > 5)'::jsonpath, '{}'::jsonb, false) AND jsonb_path_exists(experience, '$[*]?(@."field" == "backend dev" && @."years" > 5)'::jsonpath, '{}'::jsonb, false)) |
EXPLAIN
QUERY PLAN |
---|
Limit (cost=12.00..16.02 rows=1 width=36) |
-> Bitmap Heap Scan on users (cost=12.00..16.02 rows=1 width=36) |
Recheck Cond: ((experience @? '$[*]?(@."field" == "devops" && @."years" > 5)'::jsonpath) AND (experience @? '$[*]?(@."field" == "backend dev" && @."years" > 5)'::jsonpath)) |
-> Bitmap Index Scan on users_exp_gin_idx (cost=0.00..12.00 rows=1 width=0) |
Index Cond: ((experience @? '$[*]?(@."field" == "devops" && @."years" > 5)'::jsonpath) AND (experience @? '$[*]?(@."field" == "backend dev" && @."years" > 5)'::jsonpath)) |
EXPLAIN
?column? |
---|
SELECT * FROM users WHERE experience @? '$[*] ? (@.field == "devops" && @.years > 5)'::jsonpath AND experience @? '$[*] ? (@.field == "java" && @.years > 6)'::jsonpath AND experience @? '$[*] ? (@.field == "ui/ux" && @.years > 2)'::jsonpath LIMIT 3 |
SELECT 1
id | experience |
---|---|
2 | [{"field": "devops", "years": 6}, {"field": "java", "years": 7}, {"field": "ui/ux", "years": 3}] |
SELECT 1
CREATE FUNCTION
id | experience |
---|---|
1 | [{"field": "devops", "years": 9}, {"field": "backend dev", "years": 7}] |
SELECT 1
ERROR: Parameter $2 (_filter_arr) must be a JSON array with keys "field" and "years" in every object. Invalid input was: >>[{"field": "devops", "years": 5}, {"field": "backend dev", "wrong_key": 6}]<< CONTEXT: PL/pgSQL function f_users_with_experience(jsonb,integer) line 7 at RAISE
ERROR: cannot extract elements from an object CONTEXT: SQL statement "SELECT 'SELECT * FROM users WHERE experience @? ' || string_agg(quote_nullable(format('$[*] ? (@.field == %s && @.years > %s)' , f->'field' , f->'years')) , E'\nAND experience @? ') || E'\nLIMIT ' || _limit FROM jsonb_array_elements(_filter_arr) f" PL/pgSQL function f_users_with_experience(jsonb,integer) line 11 at SQL statement