0

I have table 'MyTable' containing the column 'observations' of type jsonb. The Json structure is as following:

{
  ...
  obsList: [
    {
      species: 'Goldfinch',
      number: 2
    },
    {
      species: 'House sparrow',
      number: 4
    },
    ...
  ]
}

If I want to query all the observations of species I can run the query:

select obs from  "MyTable" t, jsonb_array_elements(t.observations->'obsList') obs where obs->>'species'='Goldfinch'

How do I make the same query using the Supabase js Client library?

I tried:

this.supabase.from('MyTable')
  .select('jsonb_array_elements(observations->\'obsList\') as obs')
  .eq('obs:species', 'Goldfinch')

and

this.supabase.from('MyTable')
  .select('observations->obsList')
  .contains('jsonb_array_elements(o.observations->\'obsList\')', {species: 'Goldfinch'})

but I get the error:

column MyTable.jsonb_array_elements does not exist

3
  • 1
    For complex filtering like this, use Postgres functions. supabase.com/docs/guides/database/functions Commented Feb 19, 2024 at 8:04
  • Yes I figured out that was the best strategy. It's too bad we can't make raw queries. Commented Feb 19, 2024 at 13:49
  • @F_sants_ I think raw queries would be too dangerous to execute, even in a limited environment. Commented Feb 23, 2024 at 23:27

2 Answers 2

1

As @dshukertjr mentioned, PostgreSQL functions (and views) are the best alternative to tackle complex queries.

To give a concrete example, you could create this view:

create "MyTableObs" as
  select obs
  from "MyTable" t, jsonb_array_elements(t.observations->'obsList') obs;

And do the filtering with Supabase.js:

this.supabase.from('MyTableObs')
  .select()
  .eq('obs->>species', 'Goldfinch')
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Laurence, I ended up using a function, but views also works very well.
0

You can query for specific array elements in JSONB column using the Superbase JS client:

const { data, error } = await superbase
 .from('MyTable)
 .select('observations:obsList(*)')
 .contains('observations.obsList[species]', 'Goldfinch')

1 Comment

Hi NItesh, sorry but doesn't work. The second argument of contains must be an object. Moreover, shouldn't you access the json properties with ->?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.