Skip to content

Commit 1d4afff

Browse files
author
Nikita Glukhov
committed
Add docs for jsonb_laxpath_value_ops and for jsonpath debug functions
1 parent c274345 commit 1d4afff

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

README.md

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,14 @@ for more examples.
220220
GIN indexes
221221
-----------
222222

223-
JsQuery extension contains two operator classes (opclasses) for GIN which
223+
JsQuery extension contains three operator classes (opclasses) for GIN which
224224
provide different kinds of query optimization.
225225

226226
* `jsonb_path_value_ops`
227+
* `jsonb_laxpath_value_ops`
227228
* `jsonb_value_path_ops`
228229

229-
In each of two GIN opclasses jsonb documents are decomposed into entries. Each
230+
In each of GIN opclasses jsonb documents are decomposed into entries. Each
230231
entry is associated with particular value and it's path. Difference between
231232
opclasses is in the entry representation, comparison and usage for search
232233
optimization.
@@ -247,7 +248,7 @@ same `#` sign in the path.
247248

248249
Major problem in the entries representation is its size. In the given example
249250
key "a" is presented three times. In the large branchy documents with long
250-
keys size of naive entries representation becomes unreasonable. Both opclasses
251+
keys size of naive entries representation becomes unreasonable. All opclasses
251252
address this issue but in a slightly different way.
252253

253254
### `jsonb_path_value_ops`
@@ -263,6 +264,21 @@ is hashed and it is higher part of entry we need to know the full path to
263264
the value in order to use it for search. However, once path is specified
264265
we can use both exact and range searches very efficiently.
265266

267+
### `jsonb_laxpath_value_ops`
268+
269+
`jsonb_laxpath_value_ops` differs from the `jsonb_path_value_ops` only in
270+
that it skips array path items from the hashing. So, the jsonb document above
271+
would be decomposed into following entries:
272+
273+
* `(hash("a", "b"); "xyz")`
274+
* `(hash("a", "c"); true)`
275+
* `(hash("a"); 10)`
276+
* `(hash("d", "e"); 7)`
277+
* `(hash("d", "e"); false)`
278+
279+
Skipping array items greatly simplifies extraction of lax JSON path queries –
280+
there is no need to extract all possible unwrapped paths (see example for
281+
`gin_debug_jsonpath_path_value()` below).
266282

267283
### `jsonb_value_path_ops`
268284

@@ -287,8 +303,15 @@ Unfortunately, opclasses aren't allowed to do any custom output to the
287303
EXPLAIN. That's why JsQuery provides following functions which allows to see
288304
how particular opclass optimizes given query.
289305

290-
* gin\_debug\_query\_path\_value(jsquery) – for jsonb\_path\_value\_ops
291-
* gin\_debug\_query\_value\_path(jsquery) – for jsonb\_value\_path\_ops
306+
* `jsonb_path_value_ops`:
307+
- `gin_debug_query_path_value(jsquery)`
308+
- `gin_debug_jsonpath_path_value(jsonpath)`
309+
* `jsonb_laxpath_value_ops`:
310+
- `gin_debug_query_laxpath_value(jsquery)`
311+
- `gin_debug_jsonpath_laxpath_value(jsonpath)`
312+
* `jsonb_value_path_ops`:
313+
- `gin_debug_query_value_path(jsquery)`
314+
- `gin_debug_jsonpath_value_path(jsonpath)`
292315

293316
Result of these functions is a textual representation of query tree which
294317
leafs are GIN search entries. Following examples show different results of
@@ -308,6 +331,31 @@ query optimization by different opclasses.
308331
*.y = 1 , entry 1 +
309332
y = 2 , entry 2 +
310333

334+
Examples for nearly equivalent JSON path query:
335+
336+
# SELECT gin_debug_jsonpath_value_path('$.x == 1 && ($.**.y == 1 || $.y == 2)');
337+
gin_debug_jsonpath_value_path
338+
-------------------------------
339+
AND +
340+
OR +
341+
*.y = 1 , entry 0 +
342+
y = 2 , entry 1 +
343+
x = 1 , entry 2 +
344+
345+
# SELECT gin_debug_jsonpath_path_value('$.x == 1 && ($.**.y == 1 || $.y == 2)');
346+
gin_debug_jsonpath_path_value
347+
-------------------------------
348+
OR +
349+
#.x = 1 , entry 0 +
350+
#.x.# = 1 , entry 1 +
351+
x = 1 , entry 2 +
352+
x.# = 1 , entry 3 +
353+
354+
# SELECT gin_debug_jsonpath_laxpath_value('$.x == 1 && ($.**.y == 1 || $.y == 2)');
355+
gin_debug_jsonpath_laxpath_value
356+
----------------------------------
357+
x = 1 , entry 0 +
358+
311359
Unfortunately, jsonb have no statistics yet. That's why JsQuery optimizer has
312360
to do imperative decision while selecting conditions to be evaluated using
313361
index. This decision is made by assumption that some condition types are less

0 commit comments

Comments
 (0)