简体   繁体   中英

PostgreSQL array of object intersection

Given I have rows in my database, with a JSONB column that holds an array of items as such:

[
  {"type": "human", "name": "Alice"},
  {"type": "dog", "name": "Fido"},
  {"type": "dog", "name": "Pluto"}
]

I need to be able to query rows based on this column. The query I want to write is a check to see if my array argument intersects, at any point, with this column.

Eg:

  • If I search for [{"type": "human", "name": "Alice"}] , I should get a hit.
  • If I search for [{"type": "human", "name": "Alice"}, {"type": "dog", "name": "Doggy"}] I should also get a hit (Since one of the objects intersects)

I've tried using the ?| operator, but according to the docs, comparison is only made by keys. I need to match the entire jsonb object

You can use exists with cross join :

select t.* from tbl t where exists (select 1 from jsonb_array_elements(t.items) v 
   cross join jsonb_array_elements('[{"type": "human", "name": "Alice"}, {"type": "dog", "name": "Doggy"}]'::jsonb) v1 
   where v.value = v1.value)

See fiddle .

As a function:

create or replace function get_results(param jsonb) 
  returns table(items jsonb)
as $$
  select t.* from tbl t where exists (select 1 from jsonb_array_elements(t.items) v 
   cross join jsonb_array_elements(param) v1 
   where v.value = v1.value)
$$ language sql;

See fiddle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM