Experimental JSONPath engine for querying massive streamed datasets.
The rsonpath crate provides a JSONPath parser and a query execution engine rq,
which utilizes SIMD instructions to provide massive throughput improvements over conventional engines.
Benchmarks of rsonpath against a reference no-SIMD engine on the
Pison dataset. NOTE: Scale is logarithmic!
To run a JSONPath query on a file execute:
rq '$..a.b' ./file.jsonIf the file is omitted, the engine reads standard input. JSON can also be passed inline:
$ rq '$..a.b' --json '{"c":{"a":{"b":42}}}'
42
For details, consult rq --help or the rsonbook.
The result of running a query is a sequence of matched values, delimited by newlines.
Alternatively, passing --result count returns only the number of matches, which might be much faster.
For other result modes consult the --help usage page.
See Releases for precompiled binaries for all first-class support targets.
Easiest way to install is via cargo.
$ cargo install rsonpath
...If maximum speed is paramount, you should install rsonpath with native CPU instructions support.
This will result in a binary that is not portable and might work incorrectly on any other machine,
but will squeeze out every last bit of throughput.
To do this, run the following cargo install variant:
$ RUSTFLAGS="-C target-cpu=native" cargo install rsonpath
...Check out the relevant chapter in the rsonbook.
The project is actively developed and currently supports only a subset of the JSONPath query language. A query is a sequence of segments, each containing one or more selectors.
| Segment | Syntax | Supported | Since | Tracking Issue |
|---|---|---|---|---|
| Child segment (single) | [<selector>] |
âď¸ | v0.1.0 | |
| Child segment (multiple) | [<selector1>,...,<selectorN>] |
â | ||
| Descendant segment (single) | ..[<selector>] |
âď¸ | v0.1.0 | |
| Descendant segment (multiple) | ..[<selector1>,...,<selectorN>] |
â |
| Selector | Syntax | Supported | Since | Tracking Issue |
|---|---|---|---|---|
| Root | $ |
âď¸ | v0.1.0 | |
| Name | .<member>, [<member>] |
âď¸ | v0.1.0 | |
| Wildcard | .*, ..*, [*] |
âď¸ | v0.4.0 | |
| Index (array index) | [<index>] |
âď¸ | v0.5.0 | |
| Index (array index from end) | [-<index>] |
â | ||
| Array slice (forward, positive bounds) | [<start>:<end>:<step>] |
âď¸ | v0.9.0 | #152 |
| Array slice (forward, arbitrary bounds) | [<start>:<end>:<step>] |
â | ||
| Array slice (backward, arbitrary bounds) | [<start>:<end>:-<step>] |
â | ||
| Filters â existential tests | [?<path>] |
â | #154 | |
| Filters â const atom comparisons | [?<path> <binop> <atom>] |
â | #156 | |
| Filters â logical expressions | &&, ||, ! |
â | ||
| Filters â nesting | [?<expr>[?<expr>]...] |
â | ||
| Filters â arbitrary comparisons | [?<path> <binop> <path>] |
â | ||
| Filters â function extensions | [?func(<path>)] |
â |
The crate is continuously built and tested for all Tier 1 Rust targets. Pre-built binaries are also available for some Tier 2 targets, but without testing. Currently, these are MUSL targets -- if you require other binaries create an issue. SIMD is available on x86 and ARM (64-bit) platforms.
| Target triple | nosimd build | SIMD support | Continuous testing | Tracking issues |
|---|---|---|---|---|
| aarch64-apple-darwin | âď¸ | âď¸ | âď¸ | |
| aarch64-pc-windows-msvc | âď¸ | âď¸ | âď¸ | |
| aarch64-unknown-linux-gnu | âď¸ | âď¸ | âď¸ | |
| i686-pc-windows-msvc | âď¸ | âď¸ | âď¸ | |
| i686-unknown-linux-gnu | âď¸ | âď¸ | âď¸ | |
| x86_64-pc-windows-gnu | âď¸ | âď¸ | âď¸ | |
| x86_64-pc-windows-msvc | âď¸ | âď¸ | âď¸ | |
| x86_64-unknown-linux-gnu | âď¸ | âď¸ | âď¸ | |
| aarch64-unknown-linux-musl | âď¸ | âď¸ | â | |
| i686-unknown-linux-musl | âď¸ | âď¸ | â | |
| x86_64-unknown-linux-musl | âď¸ | âď¸ | â |
SIMD support is enabled on a module-by-module basis. Generally, any CPU released in the past decade supports AVX2, which enables all available optimizations. On ARM, we support NEON.
Older CPUs with SSE2 or higher get partial support. You can check what exactly is enabled
with rq --version â check the SIMD support field:
$ rq --version
rq 0.9.1
Commit SHA: c024e1bab89610455537b77aed249d2a05a81ed6
Features: default,simd
Opt level: 3
Target triple: x86_64-unknown-linux-gnu
Codegen flags: link-arg=-fuse-ld=lld
SIMD support: avx2;fast_quotes;fast_popcntThe fast_quotes capability depends on the pclmulqdq instruction (on x86) or the aes feature (ARM),
and fast_popcnt on the popcnt instruction (always available on ARM).
Not all selectors are supported, see the support table above.
The engine assumes that every object in the input JSON has no duplicate keys. Behavior on duplicate keys is not guaranteed to be stable, but currently the engine will simply match the first such key.
$ rq '$.key' --json '{"key":"value","key":"other value"}'
"value"
The engine does not parse unicode escape sequences in member names.
This means that a key "a" is different from a key "\u0041", even though semantically they represent the same string.
This is actually as-designed with respect to the current JSONPath spec.
Parsing unicode sequences is costly, so the support for this was postponed
in favour of high performance. This is tracked as #117.
The gist is: fork, implement, make a PR back here. More details are in the CONTRIBUTING doc.
The dev workflow utilizes just.
Use the included Justfile. It will automatically install Rust for you using the rustup tool if it detects there is no Cargo in your environment.
$ just build
...
$ just test
...Benchmarks for rsonpath are located in the benchmark crate of this repository.
Easiest way to run all the benchmarks is just bench within the directory crates/rsonpath-benchmarks . For details, look at the README in this directory.
We have a paper on rsonpath to be published at ASPLOS '24! You can read it
here.
This project was conceived as my thesis. You can read it for details on the theoretical background on the engine and details of its implementation.
We also have a short talk from ASPLOS 2024 about rsonpath!
https://gienieczko.com/asplos-2024-talk.mp4
(excuse the audio quality, the sound in the source video was corrupted and we had to salvage)
Showing direct dependencies, for full graph see below.
cargo tree --package rsonpath --edges normal --depth 1rsonpath v0.10.1 (/home/mat/src/rsonpath/crates/rsonpath)
âââ clap v4.6.1
âââ color-eyre v0.6.5
âââ eyre v0.6.12
âââ log v0.4.30
âââ rsonpath-lib v0.10.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
âââ rsonpath-syntax v0.4.2 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
âââ simple_logger v5.2.0
[build-dependencies]
âââ rustflags v0.1.7
âââ vergen v9.1.0
â [build-dependencies]
âââ vergen-git2 v9.1.0
[build-dependencies]cargo tree --package rsonpath-lib --edges normal --depth 1rsonpath-lib v0.10.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
âââ cfg-if v1.0.4
âââ log v0.4.30
âââ memmap2 v0.9.10
âââ rsonpath-syntax v0.4.2 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
âââ serde v1.0.228
âââ smallvec v1.15.1
âââ static_assertions v1.1.0
âââ thiserror v2.0.18
âââ vector-map v1.1.0clapâ standard crate to provide the CLI.color-eyre,eyreâ more accessible error messages for the parser.log,simple-loggerâ diagnostic logs during compilation and execution.cfg-ifâ used to support SIMD and no-SIMD versions.memmap2â for fast reading of source files via a memory map instead of buffered copies.nomâ for parser implementation.serdeâ optional dependency under a feature, used to allow serialization/deserialization of compiled queries.smallvecâ crucial for small-stack performance.static_assertionsâ additional reliability by some constant assumptions validated at compile time.thiserrorâ idiomaticErrorimplementations.vector_mapâ used in the query compiler for measurably better performance.
cargo tree --package rsonpath --edges normalrsonpath v0.10.1 (/home/mat/src/rsonpath/crates/rsonpath)
âââ clap v4.6.1
â âââ clap_builder v4.6.0
â â âââ anstream v1.0.0
â â â âââ anstyle v1.0.14
â â â âââ anstyle-parse v1.0.0
â â â â âââ utf8parse v0.2.2
â â â âââ anstyle-query v1.1.5
â â â â âââ windows-sys v0.61.2
â â â â âââ windows-link v0.2.1
â â â âââ anstyle-wincon v3.0.11
â â â â âââ anstyle v1.0.14
â â â â âââ once_cell_polyfill v1.70.2
â â â â âââ windows-sys v0.61.2 (*)
â â â âââ colorchoice v1.0.5
â â â âââ is_terminal_polyfill v1.70.2
â â â âââ utf8parse v0.2.2
â â âââ anstyle v1.0.14
â â âââ clap_lex v1.1.0
â â âââ strsim v0.11.1
â â âââ terminal_size v0.4.4
â â âââ rustix v1.1.4
â â â âââ bitflags v2.11.1
â â â âââ errno v0.3.14
â â â â âââ libc v0.2.186
â â â â âââ windows-sys v0.61.2 (*)
â â â âââ libc v0.2.186
â â â âââ linux-raw-sys v0.12.1
â â â âââ windows-sys v0.61.2 (*)
â â âââ windows-sys v0.61.2 (*)
â âââ clap_derive v4.6.1 (proc-macro)
â âââ heck v0.5.0
â âââ proc-macro2 v1.0.106
â â âââ unicode-ident v1.0.24
â âââ quote v1.0.45
â â âââ proc-macro2 v1.0.106 (*)
â âââ syn v2.0.117
â âââ proc-macro2 v1.0.106 (*)
â âââ quote v1.0.45 (*)
â âââ unicode-ident v1.0.24
âââ color-eyre v0.6.5
â âââ backtrace v0.3.76
â â âââ addr2line v0.25.1
â â â âââ gimli v0.32.3
â â âââ cfg-if v1.0.4
â â âââ libc v0.2.186
â â âââ miniz_oxide v0.8.9
â â â âââ adler2 v2.0.1
â â âââ object v0.37.3
â â â âââ memchr v2.8.1
â â âââ rustc-demangle v0.1.27
â â âââ windows-link v0.2.1
â âââ eyre v0.6.12
â â âââ indenter v0.3.4
â â âââ once_cell v1.21.4
â âââ indenter v0.3.4
â âââ once_cell v1.21.4
â âââ owo-colors v4.3.0
âââ eyre v0.6.12 (*)
âââ log v0.4.30
âââ rsonpath-lib v0.10.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
â âââ cfg-if v1.0.4
â âââ log v0.4.30
â âââ memmap2 v0.9.10
â â âââ libc v0.2.186
â âââ rsonpath-syntax v0.4.2 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
â â âââ nom v8.0.0
â â â âââ memchr v2.8.1
â â âââ owo-colors v4.3.0
â â âââ thiserror v2.0.18
â â â âââ thiserror-impl v2.0.18 (proc-macro)
â â â âââ proc-macro2 v1.0.106 (*)
â â â âââ quote v1.0.45 (*)
â â â âââ syn v2.0.117 (*)
â â âââ unicode-width v0.2.2
â âââ smallvec v1.15.1
â âââ static_assertions v1.1.0
â âââ thiserror v2.0.18 (*)
â âââ vector-map v1.1.0
âââ rsonpath-syntax v0.4.2 (/home/mat/src/rsonpath/crates/rsonpath-syntax) (*)
âââ simple_logger v5.2.0
âââ colored v3.1.1
â âââ windows-sys v0.61.2 (*)
âââ log v0.4.30
âââ time v0.3.47
â âââ deranged v0.5.8
â â âââ powerfmt v0.2.0
â âââ itoa v1.0.18
â âââ libc v0.2.186
â âââ num-conv v0.2.2
â âââ num_threads v0.1.7
â â âââ libc v0.2.186
â âââ powerfmt v0.2.0
â âââ time-core v0.1.8
â âââ time-macros v0.2.27 (proc-macro)
â âââ num-conv v0.2.2
â âââ time-core v0.1.8
âââ windows-sys v0.61.2 (*)
[build-dependencies]
âââ rustflags v0.1.7
âââ vergen v9.1.0
â âââ anyhow v1.0.102
â âââ cargo_metadata v0.23.1
â â âââ camino v1.2.2
â â â âââ serde_core v1.0.228
â â â âââ serde_derive v1.0.228 (proc-macro)
â â â âââ proc-macro2 v1.0.106 (*)
â â â âââ quote v1.0.45 (*)
â â â âââ syn v2.0.117 (*)
â â âââ cargo-platform v0.3.3
â â â âââ serde v1.0.228
â â â â âââ serde_core v1.0.228 (*)
â â â â âââ serde_derive v1.0.228 (proc-macro) (*)
â â â âââ serde_core v1.0.228 (*)
â â âââ semver v1.0.28
â â â âââ serde v1.0.228 (*)
â â â âââ serde_core v1.0.228 (*)
â â âââ serde v1.0.228 (*)
â â âââ serde_json v1.0.150
â â â âââ itoa v1.0.18
â â â âââ memchr v2.8.1
â â â âââ serde v1.0.228 (*)
â â â âââ serde_core v1.0.228 (*)
â â â âââ zmij v1.0.21
â â âââ thiserror v2.0.18 (*)
â âââ derive_builder v0.20.2
â â âââ derive_builder_macro v0.20.2 (proc-macro)
â â âââ derive_builder_core v0.20.2
â â â âââ darling v0.20.11
â â â â âââ darling_core v0.20.11
â â â â â âââ fnv v1.0.7
â â â â â âââ ident_case v1.0.1
â â â â â âââ proc-macro2 v1.0.106 (*)
â â â â â âââ quote v1.0.45 (*)
â â â â â âââ strsim v0.11.1
â â â â â âââ syn v2.0.117 (*)
â â â â âââ darling_macro v0.20.11 (proc-macro)
â â â â âââ darling_core v0.20.11 (*)
â â â â âââ quote v1.0.45 (*)
â â â â âââ syn v2.0.117 (*)
â â â âââ proc-macro2 v1.0.106 (*)
â â â âââ quote v1.0.45 (*)
â â â âââ syn v2.0.117 (*)
â â âââ syn v2.0.117 (*)
â âââ regex v1.12.3
â â âââ aho-corasick v1.1.4
â â â âââ memchr v2.8.1
â â âââ memchr v2.8.1
â â âââ regex-automata v0.4.14
â â â âââ aho-corasick v1.1.4 (*)
â â â âââ memchr v2.8.1
â â â âââ regex-syntax v0.8.10
â â âââ regex-syntax v0.8.10
â âââ rustc_version v0.4.1
â â âââ semver v1.0.28 (*)
â âââ vergen-lib v9.1.0
â âââ anyhow v1.0.102
â âââ derive_builder v0.20.2 (*)
â [build-dependencies]
â âââ rustversion v1.0.22 (proc-macro)
â [build-dependencies]
â âââ rustversion v1.0.22 (proc-macro)
âââ vergen-git2 v9.1.0
âââ anyhow v1.0.102
âââ derive_builder v0.20.2 (*)
âââ git2 v0.20.4
â âââ bitflags v2.11.1
â âââ libc v0.2.186
â âââ libgit2-sys v0.18.4+1.9.3
â â âââ libc v0.2.186
â â âââ libz-sys v1.1.28
â â âââ libc v0.2.186
â â [build-dependencies]
â â âââ cc v1.2.62
â â â âââ find-msvc-tools v0.1.9
â â â âââ jobserver v0.1.34
â â â â âââ getrandom v0.3.4
â â â â â âââ cfg-if v1.0.4
â â â â â âââ libc v0.2.186
â â â â â âââ r-efi v5.3.0
â â â â â âââ wasip2 v1.0.3+wasi-0.2.9
â â â â â âââ wit-bindgen v0.57.1
â â â â âââ libc v0.2.186
â â â âââ libc v0.2.186
â â â âââ shlex v1.3.0
â â âââ pkg-config v0.3.33
â â âââ vcpkg v0.2.15
â â [build-dependencies]
â â âââ cc v1.2.62 (*)
â â âââ pkg-config v0.3.33
â âââ log v0.4.30
â âââ url v2.5.8
â âââ form_urlencoded v1.2.2
â â âââ percent-encoding v2.3.2
â âââ idna v1.1.0
â â âââ idna_adapter v1.2.2
â â â âââ icu_normalizer v2.2.0
â â â â âââ icu_collections v2.2.0
â â â â â âââ displaydoc v0.2.6 (proc-macro)
â â â â â â âââ proc-macro2 v1.0.106 (*)
â â â â â â âââ quote v1.0.45 (*)
â â â â â â âââ syn v2.0.117 (*)
â â â â â âââ potential_utf v0.1.5
â â â â â â âââ zerovec v0.11.6
â â â â â â âââ yoke v0.8.2
â â â â â â â âââ stable_deref_trait v1.2.1
â â â â â â â âââ yoke-derive v0.8.2 (proc-macro)
â â â â â â â â âââ proc-macro2 v1.0.106 (*)
â â â â â â â â âââ quote v1.0.45 (*)
â â â â â â â â âââ syn v2.0.117 (*)
â â â â â â â â âââ synstructure v0.13.2
â â â â â â â â âââ proc-macro2 v1.0.106 (*)
â â â â â â â â âââ quote v1.0.45 (*)
â â â â â â â â âââ syn v2.0.117 (*)
â â â â â â â âââ zerofrom v0.1.8
â â â â â â â âââ zerofrom-derive v0.1.7 (proc-macro)
â â â â â â â âââ proc-macro2 v1.0.106 (*)
â â â â â â â âââ quote v1.0.45 (*)
â â â â â â â âââ syn v2.0.117 (*)
â â â â â â â âââ synstructure v0.13.2 (*)
â â â â â â âââ zerofrom v0.1.8 (*)
â â â â â â âââ zerovec-derive v0.11.3 (proc-macro)
â â â â â â âââ proc-macro2 v1.0.106 (*)
â â â â â â âââ quote v1.0.45 (*)
â â â â â â âââ syn v2.0.117 (*)
â â â â â âââ utf8_iter v1.0.4
â â â â â âââ yoke v0.8.2 (*)
â â â â â âââ zerofrom v0.1.8 (*)
â â â â â âââ zerovec v0.11.6 (*)
â â â â âââ icu_normalizer_data v2.2.0
â â â â âââ icu_provider v2.2.0
â â â â â âââ displaydoc v0.2.6 (proc-macro) (*)
â â â â â âââ icu_locale_core v2.2.0
â â â â â â âââ displaydoc v0.2.6 (proc-macro) (*)
â â â â â â âââ litemap v0.8.2
â â â â â â âââ tinystr v0.8.3
â â â â â â â âââ displaydoc v0.2.6 (proc-macro) (*)
â â â â â â â âââ zerovec v0.11.6 (*)
â â â â â â âââ writeable v0.6.3
â â â â â â âââ zerovec v0.11.6 (*)
â â â â â âââ writeable v0.6.3
â â â â â âââ yoke v0.8.2 (*)
â â â â â âââ zerofrom v0.1.8 (*)
â â â â â âââ zerotrie v0.2.4
â â â â â â âââ displaydoc v0.2.6 (proc-macro) (*)
â â â â â â âââ yoke v0.8.2 (*)
â â â â â â âââ zerofrom v0.1.8 (*)
â â â â â âââ zerovec v0.11.6 (*)
â â â â âââ smallvec v1.15.1
â â â â âââ zerovec v0.11.6 (*)
â â â âââ icu_properties v2.2.0
â â â âââ icu_collections v2.2.0 (*)
â â â âââ icu_locale_core v2.2.0 (*)
â â â âââ icu_properties_data v2.2.0
â â â âââ icu_provider v2.2.0 (*)
â â â âââ zerotrie v0.2.4 (*)
â â â âââ zerovec v0.11.6 (*)
â â âââ smallvec v1.15.1
â â âââ utf8_iter v1.0.4
â âââ percent-encoding v2.3.2
âââ time v0.3.47
â âââ deranged v0.5.8 (*)
â âââ itoa v1.0.18
â âââ libc v0.2.186
â âââ num-conv v0.2.2
â âââ num_threads v0.1.7 (*)
â âââ powerfmt v0.2.0
â âââ time-core v0.1.8
âââ vergen v9.1.0 (*)
âââ vergen-lib v9.1.0 (*)
[build-dependencies]
âââ rustversion v1.0.22 (proc-macro)