问题
I have a table users
with a jsonb
field called data
. I have to retrieve all the users that have a value in that data
column matching a given string. For example:
user1 = data: {"property_a": "a1", "property_b": "b1"}
user2 = data: {"property_a": "a2", "property_b": "b2"}
I want to retrieve any user that has a value data
matching 'b2'
, in this case that will be 'user2'
.
Any idea how to do this in an elegant way? I can retrieve all keys from data
of all users and create a query manually but that will be neither fast nor elegant.
In addition, I have to retrieve the key and value matched, but first things first.
回答1:
There is no easy way. Per documentation:
GIN indexes can be used to efficiently search for keys or key/value pairs occurring within a large number of jsonb documents (datums)
Bold emphasis mine. There is no index over all values. (Those can have non-compatible data types!) If you do not know the name(s) of all key(s) you have to inspect all JSON values in every row.
If there are just two keys like you demonstrate (or just a few well-kown keys), it's still easy enough:
SELECT *
FROM users
WHERE data->>'property_a' = 'b2' OR
data->>'property_b' = 'b2';
Can be supported with a simple expression index:
CREATE INDEX foo_idx ON users ((data->>'property_a'), (data->>'property_b'))
Or with a GIN index:
SELECT *
FROM v
WHERE data @> '{"property_a": "b2"}' OR
data @> '{"property_b": "b2"}'
CREATE INDEX bar_idx ON users USING gin (data jsonb_path_ops);
If you don't know all key names, things get complicated ...
Related:
- How do I query using fields inside the new PostgreSQL JSON datatype?
- Index for finding an element in a JSON array
回答2:
Try this query.
SELECT * FROM users
WHERE data::text LIKE '%b2%'
Of course it won't work if your key will contain such string too.
来源:https://stackoverflow.com/questions/29609161/how-to-filter-a-value-of-any-key-of-json-in-postgres