Rails - Postgres - jsonb column query - ruby-on-rails

I have a jsonb column named 'available_quantity'. which will have sample values
{ "100": 50, "1000":10 }
Now, I want to query all keys with values less than 50.
I tried this query,
Bundle.where('available_quantity #> ?', {'100': 5}.to_json)
But this one gives me all the Bundle with available_quantity containing {100: 5}.
How can I do that? Is that even possible?

You can use the ->> operator:
Bundle.where("(available_quantity->>'100')::int < 50")

Related

JSONB Querying array

I have the following a column in a PostgreSQL table that has a JSONB field with data like:
[{"id":33,"url":"","name":"test"}, {"id":45,"url":"","name":"test"}]
I'm trying to query it and return the element that matches the id. I have the following query in Rails, but it doesn't seem to be matching:
Book.where('data #> ?', '[{"id": 33}]')
Since you only need some elements in the jsonb array, you will need to transform those into records and cross join them with their parents:
Book.joins(", jsonb_array_elements(books.data) obj")
.where("obj->>'id' = '33'")
.select("obj")

ruby multiple where operator with jsonb column and non jsonb columns

I am trying to make a query that includes a jsonb column and 2 non jsonb columns.
Multiple attempts to combine them have failed but 1 nearly worked when I only used 1 other non jsonb column. I have a channel model with an 'options' store and several attributes within.
If i separate the queries they work just fine but combined they retrieve an empty array. I have made sure that if the queries did work, there is definitely data for them to return.
Non jsonb columns - works
Channel.where("platform_id = ? AND updated_at < ?",2,7.days.ago)
jsonb column - works
Channel.where("options #> ?", {valid_account: true}.to_json)
combined where operator - returns empty []
Channel.where("platform_id = ? AND updated_at < ?",2,7.days.ago).where("options #> ?", {valid_account: true}.to_json)
1 where operator with combined query - again, returns empty []
Channel.where("options = ? AND platform_id = ? AND updated_at < ?", {"valid_account" => true}.to_json, 2, 7.days.ago)
Am at a loss now and not sure how to get this all into one query... or if it's even possible.
Again... there are definitely channels that should return with the given queries above
TIA
UPDATE
Managed to get the query to work. tried nearly every combination but missed one critical one.
Channel.where("options #> ? AND platform_id = ? AND updated_at > ?", {valid_account: true}.to_json, 2, 7.days.ago)
this worked. For some reason I had used the '>#' in a separate method but not combined it for this. All working now. Thanks for the support
Answer was to include '>#' in the query for the jsonb column
Channel.where("options #> ? AND platform_id = ? AND updated_at > ?", {valid_account: true}.to_json, 2, 7.days.ago

Return activerecord results for jsonb column array count greater than given value

In my rails 5 application with a Postgresql database, there is a class Listing with a jsonb column media.
I want to return the records that have array length greater than 10 in the media column.
How would I construct that query in ActiveRecord?
Turns out it is very straightforward
Listing.where('JSONB_ARRAY_LENGTH(media) > 10')

How do I search for '%stars%' within a Postgresql array?

I am trying to find a record in a Postgresql Query, where I have a column 'alternate_names'
t.text "alternate_names", default: [], array: true
And, I would like to find the following record:
altenate_names = ['All Stars']
where my criteria is 'Stars'
In other words, how can I write the following
select * from group where '%Stars%' = ANY(alternate_names);
But this won't return my record above because it has the array ['All Stars']...so, how can I perform an ILIKE '%stars%' with an array?
if you want LIKE operator:
select * from group where alternate_names::text like '%Stars%';
Comparing text representation of array against pattern is not effective, but wildcard before pattern won't be effective in any query on text[]
You can use unnest to check for partial match of all elements in an array.
Ex:
select * from group where exists (select 1 from unnest(alternate_names) as a_names where a_names like '%Stars%');

Rails Postgres how to query a jsonb column for empty objects?

How do I get all the empty records for a jsonb column with Active Record ?
You can query for empty objects in a JSONB column using the following syntax:
Model.where("column = '{}'")

Resources