I have a Postgres table named "base" with a jsonb
field called "addresses" which stores multiple addresses for the same user.
Here is the table structure:
create table base(name text, addresses jsonb);
insert into base(name, addresses) values('John', '[{"zip":"01431000","state":"SP","number":100,"street1":"Avenida Brasil","city_name":"São Paulo"},{"zip":"01310900","state":"SP","number":200,"street1":"Avenida Paulista","city_name":"São Paulo"}]');
insert into base(name, addresses) values('Doe', '[{"zip":"01332000","state":"SP","number":250,"street1":"Rua Itapeva","city_name":"São Paulo"}]');
I’m trying to search for specific row containing an address using combination of "street1" and "number" keys using gin index on key "street1".
Here is the structure of the jsonb
field:
[
{
"zip":"01431000",
"state":"SP",
"number":100,
"street1":"Avenida Brasil",
"city_name":"São Paulo",
},
{
"zip":"01310900",
"state":"SP",
"number":200,
"street1":"Avenida Paulista",
"city_name":"São Paulo",
},
]
How I would be able to search, for example, for a row containing: to_tsquery('simple', 'paulista')
and number = 200
? I need to be able to search for partial "street1" name.
I have a index for searching by "zip" and "number":
create index base_addresses_idx on base using gin (addresses jsonb_path_ops);
And the search is really fast using this query:
select * from table. where addresses @> '[{"zip":"01431000","number":100}]';
But I am not able to query for partial "street1" name (using tsvector) and a specific number.
PS: I am using PostgreSQL 15.1
2
Answers
The solution I found to this problem was to create a materialized view with the expanded addresses field:
Then, I have created those indexes:
This way, I can query easily with an inner join between
base
andaddress
using tsvector onstreet1
andnumber
keys:Subqueries should be able to do this. For each row in base, use
jsonb_array_elements()
to locate all dictionaries containing a value instreet1
like your substring. Then from those, find any containing your other condition. Put this in aWHERE EXISTS
clause by selecting1
at each occurrence.