jonq 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jonq-0.0.1/.github/workflows/tests.yml +35 -0
- jonq-0.0.1/.gitignore +7 -0
- jonq-0.0.1/.readthedocs.yml +19 -0
- jonq-0.0.1/CONTRIBUTIONS.md +36 -0
- jonq-0.0.1/License +7 -0
- jonq-0.0.1/PKG-INFO +336 -0
- jonq-0.0.1/README.md +312 -0
- jonq-0.0.1/USAGE.md +143 -0
- jonq-0.0.1/changelog +14 -0
- jonq-0.0.1/docs/Makefile +20 -0
- jonq-0.0.1/docs/build/doctrees/api.doctree +0 -0
- jonq-0.0.1/docs/build/doctrees/contribution.doctree +0 -0
- jonq-0.0.1/docs/build/doctrees/environment.pickle +0 -0
- jonq-0.0.1/docs/build/doctrees/examples.doctree +0 -0
- jonq-0.0.1/docs/build/doctrees/index.doctree +0 -0
- jonq-0.0.1/docs/build/doctrees/installation.doctree +0 -0
- jonq-0.0.1/docs/build/doctrees/usage.doctree +0 -0
- jonq-0.0.1/docs/build/html/.buildinfo +4 -0
- jonq-0.0.1/docs/build/html/_sources/api.rst.txt +381 -0
- jonq-0.0.1/docs/build/html/_sources/contribution.rst.txt +93 -0
- jonq-0.0.1/docs/build/html/_sources/examples.rst.txt +290 -0
- jonq-0.0.1/docs/build/html/_sources/index.rst.txt +23 -0
- jonq-0.0.1/docs/build/html/_sources/installation.rst.txt +59 -0
- jonq-0.0.1/docs/build/html/_sources/usage.rst.txt +144 -0
- jonq-0.0.1/docs/build/html/_static/alabaster.css +708 -0
- jonq-0.0.1/docs/build/html/_static/basic.css +925 -0
- jonq-0.0.1/docs/build/html/_static/custom.css +1 -0
- jonq-0.0.1/docs/build/html/_static/doctools.js +156 -0
- jonq-0.0.1/docs/build/html/_static/documentation_options.js +13 -0
- jonq-0.0.1/docs/build/html/_static/file.png +0 -0
- jonq-0.0.1/docs/build/html/_static/language_data.js +199 -0
- jonq-0.0.1/docs/build/html/_static/minus.png +0 -0
- jonq-0.0.1/docs/build/html/_static/plus.png +0 -0
- jonq-0.0.1/docs/build/html/_static/pygments.css +84 -0
- jonq-0.0.1/docs/build/html/_static/pyjq.png +0 -0
- jonq-0.0.1/docs/build/html/_static/searchtools.js +620 -0
- jonq-0.0.1/docs/build/html/_static/sphinx_highlight.js +154 -0
- jonq-0.0.1/docs/build/html/api.html +531 -0
- jonq-0.0.1/docs/build/html/contribution.html +200 -0
- jonq-0.0.1/docs/build/html/examples.html +360 -0
- jonq-0.0.1/docs/build/html/genindex.html +107 -0
- jonq-0.0.1/docs/build/html/index.html +164 -0
- jonq-0.0.1/docs/build/html/installation.html +162 -0
- jonq-0.0.1/docs/build/html/objects.inv +7 -0
- jonq-0.0.1/docs/build/html/search.html +124 -0
- jonq-0.0.1/docs/build/html/searchindex.js +1 -0
- jonq-0.0.1/docs/build/html/usage.html +230 -0
- jonq-0.0.1/docs/source/_static/jonq.png +0 -0
- jonq-0.0.1/docs/source/api.rst +381 -0
- jonq-0.0.1/docs/source/conf.py +28 -0
- jonq-0.0.1/docs/source/contribution.rst +93 -0
- jonq-0.0.1/docs/source/examples.rst +290 -0
- jonq-0.0.1/docs/source/index.rst +23 -0
- jonq-0.0.1/docs/source/installation.rst +59 -0
- jonq-0.0.1/docs/source/usage.rst +144 -0
- jonq-0.0.1/fake.py +20 -0
- jonq-0.0.1/jonq/__init__.py +0 -0
- jonq-0.0.1/jonq/executor.py +33 -0
- jonq-0.0.1/jonq/jq_filter.py +327 -0
- jonq-0.0.1/jonq/main.py +59 -0
- jonq-0.0.1/jonq/query_parser.py +368 -0
- jonq-0.0.1/pyproject.toml +42 -0
- jonq-0.0.1/tests/jq_executor_test.py +45 -0
- jonq-0.0.1/tests/jq_filter_test.py +289 -0
- jonq-0.0.1/tests/jq_main_test.py +68 -0
- jonq-0.0.1/tests/jq_query_parser_test.py +242 -0
- jonq-0.0.1/tests/json_test_files/deeply_nested.json +11 -0
- jonq-0.0.1/tests/json_test_files/empty_array.json +1 -0
- jonq-0.0.1/tests/json_test_files/empty_object.json +1 -0
- jonq-0.0.1/tests/json_test_files/empty_object_array.json +1 -0
- jonq-0.0.1/tests/json_test_files/hello_world.json +1 -0
- jonq-0.0.1/tests/json_test_files/missing_fields.json +4 -0
- jonq-0.0.1/tests/json_test_files/mixed_arrays.json +1 -0
- jonq-0.0.1/tests/json_test_files/nested.json +43 -0
- jonq-0.0.1/tests/json_test_files/nested_array.json +1 -0
- jonq-0.0.1/tests/json_test_files/null_values.json +4 -0
- jonq-0.0.1/tests/json_test_files/pyjq_manual_edge_edge_test.sh +133 -0
- jonq-0.0.1/tests/json_test_files/pyjq_manual_n_edge_test.sh +84 -0
- jonq-0.0.1/tests/json_test_files/pyjq_manual_nested_test.sh +47 -0
- jonq-0.0.1/tests/json_test_files/pyjq_manual_simple_test.sh +56 -0
- jonq-0.0.1/tests/json_test_files/simple.json +20 -0
- jonq-0.0.1/tests/json_test_files/simple_number.json +1 -0
- jonq-0.0.1/tests/json_test_files/single_object.json +1 -0
- jonq-0.0.1/tests/json_test_files/special_characters_keys.json +5 -0
- jonq-0.0.1/tests/json_test_files/special_value.json +4 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ['3.9', '3.10', '3.11']
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v3
|
|
18
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
19
|
+
uses: actions/setup-python@v4
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip
|
|
25
|
+
pip install pytest pytest-cov
|
|
26
|
+
pip install -e .
|
|
27
|
+
- name: Install jq
|
|
28
|
+
run: |
|
|
29
|
+
sudo apt-get update
|
|
30
|
+
sudo apt-get install -y jq
|
|
31
|
+
- name: Test with pytest
|
|
32
|
+
run: |
|
|
33
|
+
pytest --cov=jonq tests
|
|
34
|
+
- name: Upload coverage to Codecov
|
|
35
|
+
uses: codecov/codecov-action@v3
|
jonq-0.0.1/.gitignore
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Contributing to jonq
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in helping with jonq! Here's how you can contribute:
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
1. Fork the repo
|
|
8
|
+
2. Clone your fork: `git clone https://github.com/duriantaco/jonq.git`
|
|
9
|
+
3. Install for development: `pip install -e .`
|
|
10
|
+
|
|
11
|
+
## How to Contribute
|
|
12
|
+
|
|
13
|
+
### Reporting Bugs
|
|
14
|
+
- Check if the bug is already reported
|
|
15
|
+
- Include clear steps to reproduce
|
|
16
|
+
- Mention your environment (Python version, OS)
|
|
17
|
+
|
|
18
|
+
### Submitting Changes
|
|
19
|
+
1. Create a branch: `git checkout -b fix-something`
|
|
20
|
+
2. Make your changes
|
|
21
|
+
3. Run tests: `pytest`
|
|
22
|
+
4. Commit with a clear message
|
|
23
|
+
5. Push to your fork
|
|
24
|
+
6. Open a pull request
|
|
25
|
+
|
|
26
|
+
### Code Style
|
|
27
|
+
- Follow PEP 8 basics
|
|
28
|
+
- Include docstrings for functions and classes
|
|
29
|
+
|
|
30
|
+
## Testing
|
|
31
|
+
Run `pytest` before submitting your changes.
|
|
32
|
+
|
|
33
|
+
## Need Help?
|
|
34
|
+
Open an issue with your question!
|
|
35
|
+
|
|
36
|
+
Thanks for contributing!
|
jonq-0.0.1/License
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2025 oha
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
jonq-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jonq
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: SQL-like query tool for JSON files
|
|
5
|
+
Project-URL: Homepage, https://github.com/duriantaco/jonq
|
|
6
|
+
Project-URL: Bug Tracker, https://github.com/duriantaco/jonq/issues
|
|
7
|
+
Author-email: oha <aaronoh2015@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: jq,json,query,sql
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Provides-Extra: docs
|
|
19
|
+
Requires-Dist: myst-parser; extra == 'docs'
|
|
20
|
+
Requires-Dist: sphinx; extra == 'docs'
|
|
21
|
+
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
|
|
22
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
<div align="center">
|
|
26
|
+
<img src="docs/source/_static/jonq.png" alt="jonq Logo" width="200"/>
|
|
27
|
+
|
|
28
|
+
# jonq
|
|
29
|
+
|
|
30
|
+
### Human-readable syntax for JQ
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/jonq/)
|
|
33
|
+
[](https://pypi.org/project/jonq/)
|
|
34
|
+
[](https://github.com/duriantaco/jonq/actions)
|
|
35
|
+
[](https://opensource.org/licenses/MIT)
|
|
36
|
+
[](https://jonq.readthedocs.io)
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
A Pythonish-SQL-like query tool for JSON files, built as a Python wrapper around the super awesome but difficult to use jq utility.
|
|
40
|
+
|
|
41
|
+
## Table of Contents
|
|
42
|
+
- [Overview](#overview)
|
|
43
|
+
- [Quick Start](#quick-start)
|
|
44
|
+
- [Features](#features)
|
|
45
|
+
- [jonq vs Native](#jonq-vs-native)
|
|
46
|
+
- [Installation](#installation)
|
|
47
|
+
- [Usage](#usage)
|
|
48
|
+
- [Example Simple JSON](#example-simple-json)
|
|
49
|
+
- [Example with Nested JSON](#example-with-nested-json)
|
|
50
|
+
- [Advanced Filtering](#advanced-filtering-with-complex-boolean-expressions)
|
|
51
|
+
- [Grouping and Aggregation](#grouping-and-aggregation-with-group-by)
|
|
52
|
+
- [Troubleshooting](#troubleshooting)
|
|
53
|
+
- [Known Limitations](#known-limitations)
|
|
54
|
+
- [Contributing](#contributing)
|
|
55
|
+
- [License](#license)
|
|
56
|
+
|
|
57
|
+
## Overview
|
|
58
|
+
|
|
59
|
+
jonq allows you to query JSON data using familiar Pythonish-SQL-like syntax. It translates these queries into jq filters, making it easier for users familiar with SQL and Python to extract and manipulate data from JSON files without learning the full jq syntax (it's just too complex imo).
|
|
60
|
+
|
|
61
|
+
## Features
|
|
62
|
+
|
|
63
|
+
* SQL-like Syntax: Query JSON with familiar `SELECT` statements and traverse nested JSONs with pythonic like syntax aka `abc.def`
|
|
64
|
+
* Field Selection: Choose specific fields from your JSON data
|
|
65
|
+
* Filtering: Filter your results using the `if` keyword
|
|
66
|
+
* Sorting: Order results with ascending or descending sort
|
|
67
|
+
* Pagination: Limit the number of results returned
|
|
68
|
+
* Aggregation Functions: Use functions like `sum()`, `avg()`, `count()`, `max()` and `min()`
|
|
69
|
+
|
|
70
|
+
## jonq vs Native
|
|
71
|
+
|
|
72
|
+
While jq is incredibly powerful, its syntax is a pain to use. I can't be the only one who feels that way right? jonq simplifies JSON querying with familiar, intuitive syntax:
|
|
73
|
+
|
|
74
|
+
| Task | Native jq | jonq |
|
|
75
|
+
|------|-----------|------|
|
|
76
|
+
| Select specific fields | `jq '.[] \| {name: .name, age: .age}'` | `jonq data.json "select name, age"` |
|
|
77
|
+
| Filter with condition | `jq '.[] \| select(.age > 30) \| {name, age}'` | `jonq data.json "select name, age if age > 30"` |
|
|
78
|
+
| Sort results | `jq 'sort_by(.age) \| reverse \| .[0:2]'` | `jonq data.json "select name, age sort age desc 2"` |
|
|
79
|
+
| Work with nested data | `jq '.[] \| select(.profile.address.city == "New York") \| {name, city: .profile.address.city}'` | `jonq data.json "select name, profile.address.city if profile.address.city = 'New York'"` |
|
|
80
|
+
| Count items | `jq 'map(select(.age > 25)) \| length'` | `jonq data.json "select count(*) as count_over_25 if age > 25"` |
|
|
81
|
+
| Group & aggregate | `jq 'group_by(.city) \| map({city: .[0].city, count: length})'` | `jonq data.json "select city, count(*) as user_count group by city"` |
|
|
82
|
+
| Complex filters | `jq '.[] \| select(.age > 25 and (.city == "New York" or .city == "Chicago"))'` | `jonq data.json "select * if age > 25 and (city = 'New York' or city = 'Chicago')"` |
|
|
83
|
+
|
|
84
|
+
As you can see, jonq offers:
|
|
85
|
+
- **Simpler syntax**: I'm not sure how much simpler can it get
|
|
86
|
+
- **Familiar patterns**: Py + SQL-like keywords
|
|
87
|
+
- **Readability**: For human readability
|
|
88
|
+
- **Faster development**: Write complex queries in a fraction of the time
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
### Prerequisites
|
|
93
|
+
|
|
94
|
+
- Python 3.9+
|
|
95
|
+
- jq command line tool installed (https://stedolan.github.io/jq/download/)
|
|
96
|
+
|
|
97
|
+
### Setup
|
|
98
|
+
|
|
99
|
+
1. Clone this repository:
|
|
100
|
+
`pip install jonq`
|
|
101
|
+
|
|
102
|
+
**Make sure you have jq installed:**
|
|
103
|
+
```
|
|
104
|
+
jq --version
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Quick Start
|
|
108
|
+
|
|
109
|
+
# Create a simple JSON file
|
|
110
|
+
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25}]' > data.json
|
|
111
|
+
|
|
112
|
+
# Run a query
|
|
113
|
+
jonq data.json "select name, age if age > 25"
|
|
114
|
+
# Output: [{"name":"Alice","age":30}]
|
|
115
|
+
|
|
116
|
+
## Query Syntax
|
|
117
|
+
|
|
118
|
+
The query syntax follows a simplified format:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
select <fields> [if <condition>] [sort <field> [asc|desc] [limit]]
|
|
122
|
+
```
|
|
123
|
+
where:
|
|
124
|
+
|
|
125
|
+
* `<fields>` - Comma-separated list of fields to select or aggregations
|
|
126
|
+
* `if <condition>` - Optional filtering condition
|
|
127
|
+
* `group by <fields>` - Optional grouping by one or more fields
|
|
128
|
+
* `sort <field>` - Optional field to sort by
|
|
129
|
+
* `asc|desc` - Optional sort direction (default: asc)
|
|
130
|
+
* `limit` - Optional integer to limit the number of results
|
|
131
|
+
|
|
132
|
+
## Example Simple JSON
|
|
133
|
+
|
|
134
|
+
You can also refer to the `json_test_files` for the test jsons and look up `USAGE.md` guide. Anyway let's start with `simple.json`.
|
|
135
|
+
|
|
136
|
+
Image a json like the following:
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
[
|
|
140
|
+
{
|
|
141
|
+
"id": 1,
|
|
142
|
+
"name": "Alice",
|
|
143
|
+
"age": 30,
|
|
144
|
+
"city": "New York"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"id": 2,
|
|
148
|
+
"name": "Bob",
|
|
149
|
+
"age": 25,
|
|
150
|
+
"city": "Los Angeles"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": 3,
|
|
154
|
+
"name": "Charlie",
|
|
155
|
+
"age": 35,
|
|
156
|
+
"city": "Chicago"
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### To select all fields:
|
|
162
|
+
```bash
|
|
163
|
+
jonq path/to/simple.json "select *"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Select specific fields:
|
|
167
|
+
```bash
|
|
168
|
+
jonq path/to/simple.json "select name, age"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Filter with conditions:
|
|
172
|
+
```bash
|
|
173
|
+
jonq path/to/simple.json "select name, age if age > 30"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Filter with conditions:
|
|
177
|
+
```bash
|
|
178
|
+
jonq path/to/simple.json "select name, age if age > 30"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Sorting:
|
|
182
|
+
```bash
|
|
183
|
+
jonq path/to/simple.json "select name, age sort age desc 2"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Aggregation:
|
|
187
|
+
```bash
|
|
188
|
+
jonq path/to/simple.json "select sum(age) as total_age"
|
|
189
|
+
jonq path/to/simple.json "select avg(age) as average_age"
|
|
190
|
+
jonq path/to/simple.json "select count(age) as count"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Simple enough i hope? Now let's move on to nested jsons
|
|
194
|
+
|
|
195
|
+
## Example with Nested JSON
|
|
196
|
+
|
|
197
|
+
Imagine a nested json like below:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
[
|
|
201
|
+
{
|
|
202
|
+
"id": 1,
|
|
203
|
+
"name": "Alice",
|
|
204
|
+
"profile": {
|
|
205
|
+
"age": 30,
|
|
206
|
+
"address": {
|
|
207
|
+
"city": "New York",
|
|
208
|
+
"zip": "10001"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"orders": [
|
|
212
|
+
{
|
|
213
|
+
"order_id": 101,
|
|
214
|
+
"item": "Laptop",
|
|
215
|
+
"price": 1200
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"order_id": 102,
|
|
219
|
+
"item": "Phone",
|
|
220
|
+
"price": 800
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"id": 2,
|
|
226
|
+
"name": "Bob",
|
|
227
|
+
"profile": {
|
|
228
|
+
"age": 25,
|
|
229
|
+
"address": {
|
|
230
|
+
"city": "Los Angeles",
|
|
231
|
+
"zip": "90001"
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"orders": [
|
|
235
|
+
{
|
|
236
|
+
"order_id": 103,
|
|
237
|
+
"item": "Tablet",
|
|
238
|
+
"price": 500
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Query nested fields with dot notation
|
|
246
|
+
```bash
|
|
247
|
+
jonq path/to/nested.json "select name, profile.age"
|
|
248
|
+
jonq path/to/nested.json "select name, profile.address.city"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Count items in nested fields
|
|
252
|
+
```bash
|
|
253
|
+
jonq path/to/nested.json "select name, count(orders) as order_count"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Advanced Filtering with Complex Boolean Expressions
|
|
257
|
+
|
|
258
|
+
jonq supports complex boolean conditions using AND, OR, and parentheses:
|
|
259
|
+
|
|
260
|
+
### Find users either from New York OR with orders costing more than 1000
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
jonq nested.json "select name, profile.age if profile.address.city = 'New York' or orders[0].price > 1000"
|
|
264
|
+
|
|
265
|
+
### Find users who are both under 30 AND from Los Angeles
|
|
266
|
+
jonq nested.json "select name, profile.age if profile.age < 30 and profile.address.city = 'Los Angeles'"
|
|
267
|
+
|
|
268
|
+
### Using parentheses for complex logic
|
|
269
|
+
jonq nested.json "select name, profile.age if (profile.age > 25 and profile.address.city = 'New York') or (profile.age < 26 and profile.address.city = 'Los Angeles')"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Grouping and Aggregation with GROUP BY
|
|
273
|
+
jonq supports grouping data and performing aggregations per group:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Group by city and count users in each city
|
|
277
|
+
jonq nested.json "select profile.address.city, count(*) as user_count group by profile.address.city"
|
|
278
|
+
|
|
279
|
+
# Group by city and get average age in each city
|
|
280
|
+
jonq nested.json "select profile.address.city, avg(profile.age) as avg_age group by profile.address.city"
|
|
281
|
+
|
|
282
|
+
# Group by city and get total orders and average order price
|
|
283
|
+
jonq nested.json "select profile.address.city, count(orders) as order_count, avg(orders.price) as avg_price group by profile.address.city"
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Troubleshooting
|
|
287
|
+
### Common Errors
|
|
288
|
+
#### Error: Command 'jq' not found
|
|
289
|
+
|
|
290
|
+
* Make sure jq is installed on your system
|
|
291
|
+
* Verify jq is in your PATH by running `jq --version`
|
|
292
|
+
* Install jq: https://stedolan.github.io/jq/download/
|
|
293
|
+
|
|
294
|
+
#### Error: Invalid JSON in file
|
|
295
|
+
|
|
296
|
+
* Check your JSON file for syntax errors
|
|
297
|
+
* Verify the file exists and is readable
|
|
298
|
+
* Use a JSON validator to check your file structure
|
|
299
|
+
|
|
300
|
+
#### Error: Syntax error in query
|
|
301
|
+
|
|
302
|
+
* Verify your query follows the correct syntax format
|
|
303
|
+
* Ensure field names match exactly what's in your JSON
|
|
304
|
+
* Check for missing quotes around string values in conditions
|
|
305
|
+
|
|
306
|
+
#### Error: No results returned
|
|
307
|
+
|
|
308
|
+
* Verify your condition isn't filtering out all records
|
|
309
|
+
* Check if your field names match the casing in the JSON
|
|
310
|
+
* For nested fields, ensure the dot notation path is correct
|
|
311
|
+
|
|
312
|
+
## Known Limitations
|
|
313
|
+
|
|
314
|
+
* Write Operations: jonq doesn't support writing results back to files. It's a read-only tool (or at least for now).
|
|
315
|
+
* Performance: For very large JSON files (100MB+), processing may be slow.
|
|
316
|
+
* Advanced jq Features: Some advanced jq features aren't exposed in the jonq syntax.
|
|
317
|
+
* CSV Output: Currently only outputs JSON format. CSV export is planned for future versions.
|
|
318
|
+
* Multiple File Joins: No support for joining data from multiple JSON files.
|
|
319
|
+
* Custom Functions: User-defined functions aren't supported in the current version.
|
|
320
|
+
* Date/Time Operations: Limited support for date/time parsing or manipulation.
|
|
321
|
+
|
|
322
|
+
## Docs
|
|
323
|
+
|
|
324
|
+
Docs here: `https://jonq.readthedocs.io/en/latest/`
|
|
325
|
+
|
|
326
|
+
## Contributing
|
|
327
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
328
|
+
|
|
329
|
+
## License
|
|
330
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
331
|
+
|
|
332
|
+
### Misc.
|
|
333
|
+
|
|
334
|
+
- **jq**: This tool depends on the [jq command-line JSON processor](https://stedolan.github.io/jq/), which is licensed under the MIT License. jq is copyright (C) 2012 Stephen Dolan.
|
|
335
|
+
|
|
336
|
+
The jq tool itself is not included in this package - users need to install it separately.
|