Skip to content

Commit 6fc896a

Browse files
committed
docs: add query iterator guide
1 parent 8db9143 commit 6fc896a

File tree

5 files changed

+66
-4
lines changed

5 files changed

+66
-4
lines changed

docs/query.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Query Iterators
2+
3+
**_New in version 1.1.0_**
4+
5+
In addition to [`findall()`](api.md#jsonpath.JSONPathEnvironment.findall) and [`finditer()`](api.md#jsonpath.JSONPathEnvironment.finditer), covered in the [quick start guide](./quickstart.md), Python JSONPath offers a fluent _query_ iterator interface.
6+
7+
[`Query`](api.md#jsonpath.Query) objects provide chainable methods for manipulating a [`JSONPathMatch`](api.md#jsonpath.JSONPathMatch) iterator, just like you'd get from `finditer()`. Obtain a `Query` object using the package-level `query()` function or [`JSONPathEnvironment.query()`](api.md#jsonpath.JSONPathEnvironment.query).
8+
9+
This example uses the query API to skip the first 5 matches, limit the total number of matches to 10, and get the value associated with each match.
10+
11+
```python
12+
from jsonpath import query
13+
14+
# data = ...
15+
16+
values = (
17+
query("$.some[[email protected]]", data)
18+
.skip(5)
19+
.limit(10)
20+
.values()
21+
)
22+
23+
for value in values:
24+
# ...
25+
```
26+
27+
## Chainable methods
28+
29+
The following `Query` methods all return `self` (the same `Query` instance), so method calls can be chained to further manipulate the underlying iterator.
30+
31+
| Method | Aliases | Description |
32+
| --------------- | ----------------------- | -------------------------------------------------- |
33+
| `skip(n: int)` | `drop` | Drop up to _n_ matches from the iterator. |
34+
| `limit(n: int)` | `head`, `take`, `first` | Yield at most _n_ matches from the iterator. |
35+
| `tail(n: int)` | `last` | Drop matches from the iterator up to the last _n_. |
36+
37+
## Terminal methods
38+
39+
These are terminal methods of the `Query` class. They can not be chained.
40+
41+
| Method | Aliases | Description |
42+
| ------------- | ------- | ------------------------------------------------------------------------------------------- |
43+
| `values()` | | Return an iterable of objects, one for each match in the iterable. |
44+
| `locations()` | | Return an iterable of normalized paths, one for each match in the iterable. |
45+
| `items()` | | Return an iterable of (object, normalized path) tuples, one for each match in the iterable. |
46+
| `pointers()` | | Return an iterable of `JSONPointer` instances, one for each match in the iterable. |
47+
| `first_one()` | `one` | Return the first `JSONPathMatch`, or `None` if there were no matches. |
48+
| `last_one()` | | Return the last `JSONPathMatch`, or `None` if there were no matches. |
49+
50+
## Tee
51+
52+
And finally there's `tee()`, which creates multiple independent queries from one query iterator. It is not safe to use the initial `Query` instance after calling `tee()`.
53+
54+
```python
55+
from jsonpath import query
56+
57+
it1, it2 = query("$.some[[email protected]]", data).tee()
58+
59+
head = it1.head(10) # first 10 matches
60+
tail = it2.tail(10) # last 10 matches
61+
```

docs/quickstart.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ print(data) # {'some': {'other': 'thing', 'foo': {'bar': [1], 'else': 'thing'}}
294294

295295
## What's Next?
296296

297-
Read about user-defined filter functions at [Function Extensions](advanced.md#function-extensions), or see how to make extra data available to filters with [Extra Filter Context](advanced.md#extra-filter-context).
297+
Read about the [Query Iterators](query.md) API or [user-defined filter functions](advanced.md#function-extensions). Also see how to make extra data available to filters with [Extra Filter Context](advanced.md#extra-filter-context).
298298

299299
`findall()`, `finditer()` and `compile()` are shortcuts that use the default[`JSONPathEnvironment`](api.md#jsonpath.JSONPathEnvironment). `jsonpath.findall(path, data)` is equivalent to:
300300

jsonpath/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,4 @@
7474
finditer = DEFAULT_ENV.finditer
7575
finditer_async = DEFAULT_ENV.finditer_async
7676
match = DEFAULT_ENV.match
77-
first = DEFAULT_ENV.match
7877
query = DEFAULT_ENV.query
79-
find = DEFAULT_ENV.query

jsonpath/fluent_api.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ def items(self) -> Iterable[Tuple[str, object]]:
130130
"""Return an iterable of (object, normalized path) tuples for each match."""
131131
return ((m.path, m.obj) for m in self._it)
132132

133+
# TODO: def pointers
134+
133135
def first_one(self) -> Optional[JSONPathMatch]:
134136
"""Return the first `JSONPathMatch` or `None` if there were no matches."""
135137
try:
@@ -152,7 +154,7 @@ def last_one(self) -> Optional[JSONPathMatch]:
152154
return None
153155

154156
def tee(self, n: int = 2) -> Tuple[Query, ...]:
155-
"""Return _n_ independent queries by teeing this query's match iterable.
157+
"""Return _n_ independent queries by teeing this query's iterator.
156158
157159
It is not safe to use a `Query` instance after calling `tee()`.
158160
"""

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ nav:
4747
- Guides:
4848
- JSONPath Syntax: "syntax.md"
4949
- Filter Functions: "functions.md"
50+
- Query Iterators: "query.md"
5051
- JSON Pointers: "pointers.md"
5152
- Async Support: "async.md"
5253
- API Reference:

0 commit comments

Comments
 (0)