Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Grammatical fixes of README.#51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
sokolcati merged 1 commit intomasterfromPGPRO-9079
Nov 23, 2023
Merged
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 86 additions & 88 deletionsREADME.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -84,28 +84,27 @@ Simple expression is specified as `path binary_operator value` or
than 5;
* `similar_product_ids.# = "0684824396"` – array "similar\_product\_ids"
contains string "0684824396".
* `*.color = "red"` – there is object somewhere which key "color" has value
"red".
* `*.color = "red"` – there is object somewhere which key "color" has value "red".
* `foo = *` – key "foo" exists in object.

Path selects set of JSON values to be checked using given operators. In
the simplest case path is justan key name. In general path is key names and
placeholders combined by dot signs. Path can use following placeholders:
Path selectsaset of JSON values to be checked using given operators. In
the simplest case path is justa key name. In general path is key names and
placeholders combined by dot signs. Path can usethefollowing placeholders:

* `#` – any index of array;
* `#N` – N-th index of array;
* `%` – any key of object;
* `#` – any index ofanarray;
* `#N` – N-th index ofanarray;
* `%` – any key ofanobject;
* `*` – any sequence of array indexes and object keys;
* `@#` – length of array or object,could beonly used as last component of
path;
* `$` – the whole JSON document as single value,could beonly the whole path.
* `@#` – length of array or object,mayonlybeused as the last component of
apath;
* `$` – the whole JSON document as single value,mayonly be the whole path.

Expression is true when operator is true against at least one value selected
by path.

Key names could be given either with or without double quotes. Key names
without double quotesshouldn'tcontain spaces, start with number orconcur
with jsquery keyword.
without double quotesmay notcontain spaces, start withanumber ormatch
a jsquery keyword.

The supported binary operators are:

Expand All@@ -121,78 +120,77 @@ The supported unary operators are:
* Check for type operators: `IS ARRAY`, `IS NUMERIC`, `IS OBJECT`, `IS STRING`
and `IS BOOLEAN`.

Expressionscould be complex. Complex expression is a set of expressions
Expressionscan be complex. Complex expression is a set of expressions
combined by logical operators (`AND`, `OR`, `NOT`) and grouped using braces.

Examples of complex expressions are given below.
Examples of complex expressions:

* `a = 1 AND (b = 2 OR c = 3) AND NOT d = 1`
* `x.% = true OR x.# = true`

Prefix expressions are expressions given in the form path (subexpression).
In this case path selects JSON values to be checked using given subexpression.
Prefix expressions are expressions given in the form`path (subexpression)`.
In this case path selects JSON values to be checked usingthegiven subexpression.
Check results are aggregated in the same way as in simple expressions.

* `#(a = 1 AND b = 2)` – exists element of array which a key is 1 and b key is 2
* `%($ >= 10 AND $ <= 20)` – exists object key which values is between 10 and 20

Path alsocouldcontain following special placeholders with "every" semantics:
Pathcanalso contain the following special placeholders with "every" semantics:

* `#:` – everyindexes of array;
* `%:` – every key of object;
* `#:` – everyindex of an array;
* `%:` – every key ofanobject;
* `*:` – every sequence of array indexes and object keys.

Consider following example.

%.#:($ >= 0 AND $ <= 1)

This example could be read as following: there is at least one keywhich value
is array of numerics between 0 and 1.
This example could be read as following: there is at least one keywhose value
isanarray of numerics between 0 and 1.

We can rewrite this example in the following form with extra braces.
We can rewrite this example in the following form with extra braces:

%(#:($ >= 0 AND $ <= 1))

The first placeholder `%` checks that expression in braces is true for at least
one value in object. The second placeholder `#:` checks valueto be array and
all its elements satisfy expressions in braces.
The first placeholder `%` checks thattheexpression in braces is true for at least
one value intheobject. The second placeholder `#:` checksif thevalueis an array
and thatall its elements satisfy the expressions in braces.

We can rewrite this example without `#:` placeholder as follows.
We can rewrite this example withoutthe`#:` placeholder as follows:

%(NOT #(NOT ($ >= 0 AND $ <= 1)) AND $ IS ARRAY)

In this example we transform assertion that every element of array satisfy some
condition to assertion that thereis noone elementwhichdoesn't satisfy the
samecondition.
In this example we transformtheassertion that every element of array satisfy some
condition toanassertion that thereare noelementswhichdon't satisfy the same
condition.

Some examples of using paths are given below.
Some examples of using paths:

* `numbers.#: IS NUMERIC` – every element of "numbers" array is numeric.
* `*:($ IS OBJECT OR $ IS BOOLEAN)` – JSON is a structure of nested objects
with booleans as leaf values.
* `#:.%:($ >= 0 AND $ <= 1)` – each element of array is object containing
* `#:.%:($ >= 0 AND $ <= 1)` – each element of array isanobject containing
only numeric values between 0 and 1.
* `documents.#:.% = *` – "documents" is array of objects containing at least
* `documents.#:.% = *` – "documents" isanarray of objects containing at least
one key.
* `%.#: ($ IS STRING)` – JSON object contains at least one array of strings.
* `#.% = true` – at least one array element isobjects which contains at least
* `#.% = true` – at least one array element isan object which contains at least
one "true" value.

Usage of path operators and braces need some explanation. When same path
operators are used multiple times they may refer different values while you can
refer same value multiple time by using braces and `$` operator. See following
examples.
The use of path operators and braces need some further explanation. When the same path
operators are used multiple times, they may refer to different values. If you want them
to always refer to the same value, you must use braces and the `$` operator. For example:

* `# < 10 AND # > 20` –exists element less than 10andexists another element
greater than 20.
* `#($ < 10 AND $ > 20)` –exists element which both less than 10 and greater
than 20 (impossible).
* `#($ >= 10 AND $ <= 20)` –exists element between 10 and 20.
* `# >= 10 AND # <= 20` –exists elementgreat or equal to 10 andexists
anotherelement less or equal to 20. Query can be satisfied by array with
no elements between 10 and 20, for instance [0,30].
* `# < 10 AND # > 20` –an element less than 10 exists, and another element
greater than 20 exists.
* `#($ < 10 AND $ > 20)` –an element which is both less than 10 and greater
than 20exists(impossible).
* `#($ >= 10 AND $ <= 20)` –an element between 10 and 20 exists.
* `# >= 10 AND # <= 20` –an elementgreater or equal to 10exists,andanother
element less or equal to 20 exists. Please note that this query also can be
satisfied by an array withno elements between 10 and 20, for instance [0,30].

Same rules apply whenyou searchinside objects andbranchy structures.
Same rules apply whensearchinginside objects andbranch structures.

Type checking operators and "every" placeholders are useful for document
schema validation. JsQuery matchig operator `@@` is immutable and can be used
Expand All@@ -208,9 +206,9 @@ CREATE TABLE js (
points.#:(x IS NUMERIC AND y IS NUMERIC)'::jsquery));
```

In this example check constraint validates that in "data" jsonb column:
value of "name" key is string, value of "similar_ids" key is array of numerics,
value of "points" key is array of objects which contain numeric values in
In this examplethecheck constraint validates that inthe"data" jsonb column
thevalue ofthe"name" key isastring,thevalue ofthe"similar_ids" key is an array of numerics,
and thevalue ofthe"points" key is an array of objects which contain numeric values in
"x" and "y" keys.

See our
Expand All@@ -227,11 +225,11 @@ provide different kinds of query optimization.
* jsonb\_value\_path\_ops

In each of two GIN opclasses jsonb documents are decomposed into entries. Each
entry is associated with particular value andit's path.Difference between
entry is associated withaparticular value andits path.The difference between
opclasses is in the entry representation, comparison and usage for search
optimization.

For example, jsonb document
For example,thejsonb document
`{"a": [{"b": "xyz", "c": true}, 10], "d": {"e": [7, false]}}`
would be decomposed into following entries:

Expand All@@ -241,57 +239,57 @@ would be decomposed into following entries:
* "d"."e".#.7
* "d"."e".#.false

Since JsQuery doesn't supportsearch in particular array index, we consider
Since JsQuery doesn't supportsearching in a particular array index, we consider
all array elements to be equivalent. Thus, each array element is marked with
same `#` sign inthe path.
thesame `#` sign inits path.

Major problem in the entries representation is its size. In the given example
key "a" is presented three times. In the large branchy documents with long
keyssize of naive entriesrepresentation becomesunreasonable. Both opclasses
address this issue but inaslightly differentway.
thekey "a" is presented three times. In large branchy documents with long
keyssizes of naive entries, therepresentation becomesunreasonably large.
Both opclassesaddress this issue, but in slightly differentways.

### jsonb\_path\_value\_ops

jsonb\_path\_value\_ops represents entry as pair of path hash and value.
Following pseudocode illustrates it.
Following pseudocode illustrates it:

(hash(path_item_1.path_item_2. ... .path_item_n); value)

In comparisonofentriespath hash is the higher part of entry and value is
its lower part. This determines the features of this opclass. Since path
is hashed and it is higher part of entry we need to know the full path to
the value in order to use it forsearch. However, once path is specified
When comparison entries, thepath hash is the higher part of entry and the value is
the lower part. This determines the features of this opclass. Since the path
is hashed and it's the higher part oftheentry, we need to know the full path to
a value in order to usetheit forsearching. However, once the path is specified
we can use both exact and range searches very efficiently.

### jsonb\_value\_path\_ops

jsonb\_value\_path\_ops represents entry as pair of value and bloom filter
ofpath.
jsonb\_value\_path\_ops represents entry as pair ofthevalue and a bloom filter
ofpaths:

(value; bloom(path_item_1) | bloom(path_item_2) | ... | bloom(path_item_n))

In comparison of entries value is the higher part of entry and bloom filter of
path is its lower part. This determines the features of this opclass. Since
value is the higher part of entry we canperformonly exact value search
efficiently. Range valuesearch is possible as well but we would have to
filter all the the different paths where matching values occur. Bloom filter
over path items allows indexusage for conditions containing `%` and `*` in
thevalue is the higher part ofanentry, we can only perform exact value search
effectively. Asearchover a range of valuesis possible as well, but we have to
filter all the the different paths where matching values occur.TheBloom filter
over path items allowstheindexto be used for conditions containing `%` and `*` in
their paths.

### Query optimization

JsQuery opclasses perform complex query optimization.Thus it's valuable for
JsQuery opclasses perform complex query optimization.It's valuable for a
developer or administrator to see the result of such optimization.
Unfortunately, opclasses aren't allowed todo any custom outputto the
EXPLAIN. That's why JsQuery providesfollowing functionswhich allows to see
how particular opclass optimizes given query.
Unfortunately, opclasses aren't allowed toput any custom outputin an
EXPLAIN. That's why JsQuery providesthese functionsto let you see
how particular opclass optimizes given query:

* gin\_debug\_query\_path\_value(jsquery) – for jsonb\_path\_value\_ops
* gin\_debug\_query\_value\_path(jsquery) – for jsonb\_value\_path\_ops

Resultof these functions is a textual representation of query tree which
leafs are GIN search entries. Following examples show different results of
query optimization by different opclasses.
The resultof these functions is a textual representation ofthequery tree
where leaves are GIN search entries. Following examples show different results of
query optimization by different opclasses:

# SELECT gin_debug_query_path_value('x = 1 AND (*.y = 1 OR y = 2)');
gin_debug_query_path_value
Expand All@@ -309,29 +307,29 @@ query optimization by different opclasses.

Unfortunately, jsonb have no statistics yet. That's why JsQuery optimizer has
to do imperative decision while selecting conditions to be evaluated using
index. This decision is made byassumtion that some condition types are less
selective than others.Optimizer divides conditions into following selectivity
class (listedby descending of selectivity).
index. This decision is made byassuming that some condition types are less
selective than others.The optimizer divides conditions into following selectivity
classes (listedin descendingorderof selectivity):

1. Equality (x = c)
2. Range (c1 < x < c2)
3. Inequality (x > c)
4. Is (x is type)
5. Any (x = \*)

Optimizer evades index evaluation of less selective conditions when possible.
The optimizer avoids index evaluation of less selective conditions when possible.
For example, in the `x = 1 AND y > 0` query `x = 1` is assumed to be more
selective than `y > 0`. That's why index isn't used for evaluation of `y > 0`.
selective than `y > 0`. That's whytheindex isn't used for evaluation of `y > 0`.

# SELECT gin_debug_query_path_value('x = 1 AND y > 0');
gin_debug_query_path_value
----------------------------
x = 1 , entry 0 +

With lack of statistics decisions made by optimizer can be inaccurate. That's
why JsQuery supports hints.Comments`/*-- index */`and `/*-- noindex */`
placed in the conditionsforcesoptimizer to useand not use index
correspondingly.
Withthelack of statistics, decisions made by optimizer can be inaccurate. That's
why JsQuery supports hints.The comments`/*-- index */`or `/*-- noindex */`
placed in the conditionsforce theoptimizer to useor not use an index
correspondingly:

SELECT gin_debug_query_path_value('x = 1 AND y /*-- index */ > 0');
gin_debug_query_path_value
Expand All@@ -348,11 +346,11 @@ correspondingly.
Contribution
------------

Please, notice, that JsQuery is still under development and while it's
stable and tested, it maycontains some bugs. Don't hesitate toraise
Please note that JsQuery is still under development. While it's
stable and tested, it maycontain some bugs. Don't hesitate tocreate
[issues at github](https://github.com/postgrespro/jsquery/issues) with your
bug reports.

If you're lacking of some functionality in JsQuery andfeeling power to
implement it then you're welcome to make pull requests.
Ifthere's some functionalityyou'd like to see added to JsQuery andyou feel
like you canimplement it, then you're welcome to make pull requests.


[8]ページ先頭

©2009-2025 Movatter.jp