Skip to content

Commit 4bbbd74

Browse files
committed
DOC-3179: RI tutorial restructure (part D)
1 parent 14f4f79 commit 4bbbd74

File tree

5 files changed

+348
-12
lines changed

5 files changed

+348
-12
lines changed

src/ds/json/adv-jsonpath.md

Lines changed: 190 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,191 @@
1-
## Placeholder
1+
[JSONPath](https://goessner.net/articles/JsonPath/) expressions help you access specific elements within a JSON document, which is similar to how XPATH works for XML documents.
2+
JSONPath support was added to Redis Stack in version 2.0.
3+
Before that, [a legacy form of pathing](https://redis.io/docs/data-types/json/path/#legacy-path-syntax) was supported.
4+
Only JSONPath will be discussed in this tutorial.
25

3-
This is placeholder content.
6+
You've already seen several examples of JSONPath in previous parts of this tutorial. The next sections will describe JSONPath in more complete detail.
7+
Some simple JSON documents will be used to demonstrate JSONPath's features.
8+
9+
```redis Load documents
10+
JSON.SET lit1 $ 5
11+
JSON.SET lit2 $ '"abc"'
12+
JSON.SET lit3 $ true
13+
JSON.SET lit4 $ null
14+
JSON.SET obj1 $ '{"a":1, "b":2}'
15+
JSON.SET obj2 $ '{"a":[1,2,3,"a","b","c",false,true,["a",1],{"a":1},{"b":null}], "b":5}'
16+
JSON.SET arr1 $ [1,2,3]
17+
JSON.SET arrmap $ '[{"a":1}, {"b":2}]'
18+
```
19+
20+
The returned value of a JSONPath expression is a JSON string with a top-level array of JSON serialized strings.
21+
22+
**Note**:
23+
>A JSONPath query can resolve to several locations in a JSON document. When more than one location is identified, the JSON commands apply the operation to every possible location.
24+
25+
## JSONPath syntax
26+
27+
| Syntax element | Description |
28+
|----------------|-------------|
29+
| `$` | The root (outermost JSON element), starts the path. |
30+
| `.` or `[]` | Selects a child element. |
31+
| `..` | Recursively descends through the JSON document. |
32+
| `*` | Wildcard, returns all elements. |
33+
| `[]` | Subscript operator, accesses an array element. |
34+
| `[,]` | Union, selects multiple elements. |
35+
| `[start:end:step]` | Array slice where `start`, `end`, and `step` are indexes. |
36+
| `[?(...)]` | Filters a JSON object or array. Supports comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`, `=~`), logical operators (`&&`, `\|\|`), and parentheses for grouping (`(`, `)`). |
37+
| `@` | The current element, used in filter or script expressions. |
38+
39+
## Basic usage
40+
41+
`$` represents the root of a document. When `$` is combined with `.` and/or `[]`, a child element is selected. Here are a few examples.
42+
43+
```redis $ by itself
44+
JSON.GET obj1 $ // returns the entire obj1 document
45+
```
46+
47+
```redis Select an element with $.
48+
JSON.GET obj2 $.a // returns the array pointed to by a
49+
```
50+
51+
```redis Select an element with $[...]
52+
JSON.GET arr1 $[1] // returns the second element of the arr1 array
53+
```
54+
55+
```redis Select $.a using $.[] notation
56+
JSON.GET obj2 '$.["a"]' // note the use of single quotes in this expression; they're needed to be able to use double quotes in the expression
57+
```
58+
59+
It is possible to use `$` as part of a field name.
60+
61+
```redis Using $ as part of a field name
62+
JSON.SET d $ '{"$":5, "$$":6}'
63+
JSON.GET d $.$ // returns "[5]"
64+
```
65+
66+
The use of quotes is optional when double quotes are not in use inside of an expression.
67+
Each of the following JSONPath expressions return the same value, `"[5]"`.
68+
69+
```redis Quote usage
70+
JSON.GET obj2 $.b
71+
JSON.GET obj2 $.'b'
72+
JSON.GET obj2 $'.b'
73+
```
74+
75+
**Note**:
76+
>If the current node is not an object or has no member named after the operand, an empty array is returned.
77+
78+
```redis Invalid path
79+
JSON.GET obj1 $.c // "[]" is returned
80+
```
81+
82+
```redis Combining . and []
83+
JSON.GET arrmap $[0].a
84+
```
85+
86+
## Bracket (union) expressions
87+
88+
The following syntaxes are supported:
89+
90+
- `'$["value1", "value2", ...]'`
91+
- `$[idx1, idx2, idx3, ...]`
92+
93+
Each represents a union operation, allowing you to select multiple elements.
94+
95+
For objects, return values are as follows:
96+
97+
- If the current node is an object, an array containing the values of the object’s fields, based on their names, is returned.
98+
- If the current node is an object and has no members named in the bracket expression, it is skipped.
99+
This could result in an empty array being returned.
100+
- If the current node is not an object, an empty array is returned.
101+
102+
Here are some examples:
103+
104+
```redis Bracket union examples with objects
105+
JSON.GET obj1 '$["a"]'
106+
JSON.GET obj1 '$["b","b"]'
107+
JSON.GET obj1 '$["a","c","b","d"]'
108+
JSON.GET obj1 '$["c","d"]'
109+
JSON.GET arr1 '$["a","b"]'
110+
```
111+
112+
For arrays:
113+
114+
- idx must be an integer
115+
- if idx < 0, it is replaced with min(0, idx + array-length)
116+
- if idx ≥ array-length (after normalization) - it is skipped
117+
118+
Return values are as follows:
119+
120+
- If the current node is an array, an array containing elements based on one or more 0-based indexes is returned.
121+
- If the current node is not an array, it is skipped, possibly resulting in an empty array being returned.
122+
123+
idx must be an integer
124+
if idx < 0, it is replaced with min(0, idx + array-length)
125+
if idx ≥ array-length (after normalization) - it is skipped
126+
127+
```redis Bracket union examples with arrays
128+
JSON.GET obj2 $.a[0]
129+
JSON.GET obj2 $.a[-1]
130+
JSON.GET obj2 $.a[100]
131+
JSON.GET obj2 $.a[-100]
132+
JSON.GET obj2 $.a[8][1]
133+
JSON.GET obj2 $.a[0,0,1,1]
134+
JSON.GET obj2 $.b[0]
135+
JSON.GET obj2 $.*[0]
136+
```
137+
138+
Redis Stack also supports slice syntax for arrays: `[start:`end`:`step`]`, where `start`, ``end``, and ``step`` are indexes.
139+
The following rules apply:
140+
141+
- If the current node is an array, an array containing elements extracted from an array are returned, based on a start index, an `end` index, and a `step` index.
142+
Array indexes are 0-based. Start Index is inclusive; End index is not inclusive.
143+
The following rules apply:
144+
145+
- If `start` is specified, it must be an integer.
146+
- if `start` is omitted, it is replaced with 0.
147+
- if `start` < 0, it is replaced with min(0, `start` + array-length).
148+
- if `start` > array-length, an empty array is returned.
149+
- if `end` is specified, it must be an integer.
150+
- If `end` is omitted, it is replaced with array-length.
151+
- If `end` ≥ array-length, it is replaced with array-length.
152+
- if `end` < 0, it is replaced with min(0, `end` + array-length).
153+
- If `end``start` (after normalization), an empty array is returned.
154+
- if `step` is specified, it must be a positive integer.
155+
- if `step` is omitted, it is replaced with 1.
156+
- If the current node in not an array, an empty array is returned.
157+
158+
```redis Array slice examples
159+
JSON.GET arr1 $[:]
160+
JSON.GET arr1 $[::]
161+
JSON.GET arr1 $[::2]
162+
JSON.GET arr1 $[0:1]
163+
JSON.GET arr1 $[0:2]
164+
JSON.GET lit3 $.*[:]
165+
```
166+
167+
## Wildcard expressions
168+
169+
The `*` character is a wildcard that expands depending on the type of the current node:
170+
171+
- If the current node is an array, an array containing the values of all the array’s elements is returned.
172+
173+
```redis Using * when the current node is an array
174+
JSON.GET arr1 $.* // each of the following commands return identical results
175+
JSON.GET arr1 $[*]
176+
JSON.GET arr1 $.[*]
177+
```
178+
179+
- If the current node is an object, an array containing the values of all the object’s members is returned.
180+
181+
```redis Using * when the current node is an object
182+
JSON.GET obj1 $.* // each of the following commands return identical results
183+
JSON.GET obj1 $[*]
184+
JSON.GET obj1 $.[*]
185+
```
186+
187+
- If current node is a literal, an empty array is returned.
188+
189+
```redis Using * when the current node is a literal
190+
JSON.GET lit1 $.*
191+
```

src/ds/json/arrays.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ For example, `-1` mean the last element and `-2` means the second to last elemen
3131
- `JSON.ARRTRIM` - trim an array so that it contains only the specified inclusive range of elements.
3232

3333
```redis Trim $.a to just the first 3 elements
34-
JSON.TRIM doc $.a 0 2
34+
JSON.ARRTRIM doc $.a 0 2
3535
JSON.GET doc
3636
```
3737

@@ -42,7 +42,7 @@ JSON.SET doc $ '{"a": [10, 20, 30, 40, 50]}'
4242
```
4343

4444
```redis Trim to the last two values
45-
JSON.TRIM doc $.a -2 -1
45+
JSON.ARRTRIM doc $.a -2 -1
4646
JSON.GET doc
4747
```
4848

src/ds/json/modify.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,12 @@ JSON.DEL bicycle:1 $.newkey
9898
JSON.GET bicycle:1
9999
```
100100

101-
The `JSON.CLEAR` command will empty all arrays and set all numeric values to zero.
101+
The `JSON.CLEAR` command will empty all arrays and set all numeric values to zero. A simple example will illustrate how this works.
102102

103-
```redis Clear out bicycle:1
104-
JSON.CLEAR bicycle:1
105-
JSON.GET bicycle:1
103+
```redis JSON.CLEAR usage
104+
JSON.SET doc $ '{"obj":{"a":1, "b":2}, "arr":[1,2,3], "str": "foo", "bool": true, "int": 42, "float": 3.14}'
105+
JSON.CLEAR doc $.*
106+
JSON.GET doc $
106107
```
107108

108109
As with all Redis keys, you can use the `DEL` command to delete keys entirely.

src/ds/json/more-adv-jsonpath.md

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,151 @@
1-
## Placeholder
1+
In this section of the JSONPath tutorial, filter and deep scan expressions will be presented using a set of simple documents.
22

3-
This is placeholder content.
3+
```redis Load documents
4+
JSON.SET lit1 $ 5
5+
JSON.SET lit2 $ '"abc"'
6+
JSON.SET lit3 $ true
7+
JSON.SET lit4 $ null
8+
JSON.SET obj1 $ '{"a":1, "b":2}'
9+
JSON.SET obj2 $ '{"a":[1,2,3,"a","b","c",false,true,["a",1],{"a":1},{"b":null}], "b":5}'
10+
JSON.SET obj3 $ '{"a1":"xx", "b1":"xx", "c1":"yy", "d1":".."}'
11+
JSON.SET arr1 $ [1,2,3]
12+
JSON.SET arr2 $ [[1,2,3],4,5,6]
13+
JSON.SET arrmap $ '[{"a":1}, {"b":2}]'
14+
```
15+
16+
## Deep scan (recursive decent) expressions
17+
18+
Deep scan (recursive descent) is available anywhere a name is required.
19+
All values and sub-arrays of any sub-objects are processed, and then each of their elements are processed recursively.
20+
21+
Here are a few examples:
22+
23+
```redis Deep scan of a nested array document
24+
JSON.GET arr2 $..*
25+
```
26+
27+
```redis Deep scan of a nested object document
28+
JSON.GET obj2 $..*
29+
```
30+
31+
```redis Deep scan of an object's sub-element b
32+
JSON.GET obj2 '$..["b"]'
33+
```
34+
35+
## Filter expressions
36+
37+
Filter expressions provide the ability to retrieve items using a combination of relational and logical operators.
38+
Filter expressions use the following syntax:
39+
40+
`[? filterexpr ]`
41+
42+
where `filterexpr` must evaluate to a boolean value, `true` or `false`.
43+
44+
The `@` operator, used only in filter expressions, represents the current node: an array, object, or scalar value.
45+
46+
Supported relational operators: `<`, `<=`, `==`, `>=`, `>`, `!=`, and `=~`. The last operator is used for regular expression matching, and there are two cases:
47+
48+
1. operands that match a regular expression
49+
1. operands that match a regular expression at a given path
50+
51+
Supported logical operators: `||` and `&&`.
52+
53+
### Relational filter expression examples
54+
55+
```redis Simple relational filter expressions
56+
JSON.GET arr1 '$[?@>1]'
57+
JSON.GET obj2 '$.a[?@=="a"]'
58+
```
59+
60+
```redis More filter expressions (identical results)
61+
JSON.GET obj2 '$.a[?@a==1]'
62+
JSON.GET obj2 '$.a[?@.a==1]'
63+
JSON.GET obj2 '$.a[?@*==1]'
64+
JSON.GET obj2 '$.a[?@.*==1]'
65+
```
66+
67+
Some interesting relational use cases:
68+
69+
```redis Interesting filter expressions
70+
JSON.GET obj2 '$.a[?@==@]' // returns all elements
71+
JSON.GET obj2 '$.a[?@[0]==@[0]]' // returns all elements that are non-empty arrays
72+
JSON.GET obj2 '$.a[?@*==@*]' // returns all elements that are non-empty objects
73+
```
74+
75+
#### Relational use cases using `<`, `<=`, `==`, `!=` `>=`, `>`
76+
77+
All evaluations of operand1 where operand1 and operand2 evaluate to scalar values (number, string, `true`, `false`, or `null`) of the same type and the comparison holds. When there's a mismatch in type, an empty array is returned.
78+
79+
The comparison is arithmetic for numbers and lexicographic for strings. For Booleans, `false` < `true`.
80+
81+
Neither arrays nor objects can be used as operands.
82+
83+
The `!=` operator is effective only when there's a mismatch in either type or value.
84+
85+
```redis Relational filter expressions using <, <=, >=, and >
86+
JSON.GET obj2 '$.a[?@>1]' // [2,3]
87+
JSON.GET obj2 '$.a[?1<@]' // [2,3]
88+
JSON.GET obj2 '$.a[?@>"a"]' // ["b","c"]
89+
JSON.GET obj2 '$.a[?"a"<@]' // ["b","c"]
90+
JSON.GET obj2 '$.a[?@>false]' // [true]
91+
JSON.GET obj2 '$.a[?false<@]' // [true]
92+
JSON.GET obj2 '$.a[?1<=1]' // [1,2,3,"a","b","c",false,true,["a",1],{"a":1},{"b":null}], all values
93+
JSON.GET obj2 '$.a[?@<=@]' // [1,2,3,"a","b","c",false,true], all scalar values
94+
JSON.GET obj2 '$.a[?@<=true]' // [false,true], all Boolean values
95+
JSON.GET obj2 '$.a[?(@<0 || @>=0)]' // [1,2,3], all numeric values
96+
```
97+
98+
```redis Relational filter expressions using ==
99+
JSON.GET obj2 '$.a[?@==1]' // [1]
100+
JSON.GET obj2 '$.a[?1==@]' // [1]
101+
JSON.GET obj2 '$.a[?@=="a"]' // ["a"]
102+
JSON.GET obj2 '$.a[?@==false]' // [false]
103+
JSON.GET obj2 '$.a[?@==@]' // [1,2,3,"a","b","c",false,true,["a",1],{"a":1},{"b":null}], all values
104+
JSON.GET obj2 '$.a[?1==1]' // [1,2,3,"a","b","c",false,true,["a",1],{"a":1},{"b":null}], all values
105+
```
106+
107+
```redis Relational filter expressions using !=
108+
JSON.GET obj2 '$.a[?(1!=@)]' // [2,3,"a","b","c",false,true,["a",1],{"a":1},{"b":null}]
109+
JSON.GET obj2 '$.a[?(@!="a")]' // [1,2,3,"b","c",false,true,["a",1],{"a":1},{"b":null}]
110+
```
111+
112+
#### Relational use cases using regular expression with the `=~` operator
113+
114+
**Note**:
115+
> Redis Stack uses [Rust regular expressions syntax](https://docs.rs/regex/latest/regex/#syntax). Invalid regular expressions are not evaluated.
116+
117+
There are two cases:
118+
119+
1. operands that match a specific regular expression
120+
121+
```redis Regex expressions using direct match
122+
JSON.GET obj2 '$.a[?@ =~ "(?i)"]' // ["a","b","c"]
123+
```
124+
125+
1. operands that match a regular expression at a given path
126+
127+
```redis Regex expressions using match at a specific path
128+
JSON.GET obj3 '$[?@ =~ $.a1]' // ["xx","xx"], matches of the regex "xx"
129+
JSON.GET obj3 '$[?@ =~ $.d1]' // ["xx","xx","yy",".."], matches of the regex ".." (any 2 chars)
130+
```
131+
132+
### Logical filter expression examples using `&&` and `||`
133+
134+
```redis Logical filter expression examples
135+
JSON.GET arr1 '$.*[?(@>1 && @<3)]' // [2], all operands must evaluate to true
136+
JSON.GET arr1 '$.*[?(@<2 || @>2)]' // [1,3], at least one operand must evaluate to true
137+
```
138+
139+
### Filter expression examples involving literals
140+
141+
**Note**:
142+
> Arrays and objects cannot be used as literals.
143+
144+
```redis Filter expression examples involving literals
145+
JSON.GET obj2 '$.a[?@==1]' // "[1]", number literal
146+
JSON.GET obj2 '$.a[?@=="a"]' // "[\"a\"]", string literal
147+
JSON.GET obj2 '$.a[?(@==true)]' // "[true]", Boolean literal
148+
JSON.GET obj2 '$.a[?(@==false)]' // "[false]", Boolean literal
149+
JSON.GET obj2 '$.a[?(@.b==null)]' // "[{\"b\":null}]", nil literal
150+
JSON.GET obj2 '$.a[*].*[?(@==null)]' // "[null]", nil literal
151+
```

src/ds/prob/hyperloglog.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
## Placeholder
1+
In this tutorial you will learn how to use the HyperLogLog (HLL) probabilistic data structure in a bike shop use case.
22

3-
This is placeholder content.

0 commit comments

Comments
 (0)