Jsquery: A PostgreSQL extension for searching nested jsonb objects and arrays
github.com
github.com
What do you mean by needing upfront knowledge of the structure you intend to query?
> We store these documents in a table named api, in a jsonb column named jdoc. If a GIN index is created on this column, queries like the following can make use of the index:
-- Find documents in which the key "company" has value "Magnafone"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
> However, the index could not be used for queries like the following, because though the operator ? is indexable, it is not applied directly to the indexed column jdoc: -- Find documents in which the key "tags" contains key or array element "qui"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
> Still, with appropriate use of expression indexes, the above query can use an index. If querying for particular items within the "tags" key is common, defining an index like this may be worthwhile: CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags'));
> Now, the WHERE clause jdoc -> 'tags' ? 'qui' will be recognized as an application of the indexable operator ? to the indexed expression jdoc -> 'tags'.- - -
Taking a look at the most recent docs, it seems jsonb_ops should provide similar index optimization characteristics to the index operations in the extension for the native SQL/JSON Path type. Likely with similar trade offs. Good to know!
The example in the docs is somewhat unfortunate because it can also be expressed directly on the indexed column using the jsonb containment operator, allowing the index can be used:
-- Find documents in which the key "tags" contains key or array element "qui"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
SQL/JSON path provides much greater expressivity than the containment operator so it allows more complex queries than can be expressed in terms of jsonb containment to be written directly on the indexed column enabling the index to be used.> Taking a look at the most recent docs, it seems jsonb_ops should provide similar index optimization characteristics to the index operations in the extension for the native SQL/JSON Path type. Likely with similar trade offs.
Definitely check with jsonb_path_ops too. While it doesn't cover quite as much as jsonb_ops the index is much more compact so queries are often quite a bit faster using it instead of the larger jsonb_ops index.
A few years ago I prototyped a user path analysis DB where we replaced a 25GB time series database of user events with one where each user has one row with a JSONB array representing their entire history, and querying it using jsquery with GIN indexes took milliseconds. Things like "find me all the users who added item X to their cart and then went on to purchase item Y instead".