Motor JSONPath experimental para consultar conjuntos de datos masivos transmitidos.
La caja rsonpath
proporciona un analizador JSONPath y un motor de ejecución de consultas rq
, que utiliza instrucciones SIMD para proporcionar mejoras masivas de rendimiento con respecto a los motores convencionales.
Comparaciones de rsonpath
frente a un motor de referencia sin SIMD en el conjunto de datos de Pison. NOTA: ¡La escala es logarítmica!
Para ejecutar una consulta JSONPath en un archivo, ejecute:
rq '$..a.b' ./file.json
Si se omite el archivo, el motor lee la entrada estándar. JSON también se puede pasar en línea:
$ rq ' $..a.b ' --json ' {"c":{"a":{"b":42}}} '
42
Para obtener más detalles, consulte rq --help
o el rsonbook.
El resultado de ejecutar una consulta es una secuencia de valores coincidentes, delimitados por nuevas líneas. Alternativamente, pasar --result count
devuelve solo el número de coincidencias, lo que podría ser mucho más rápido. Para otros modos de resultados, consulte la página de uso --help
.
Consulte Versiones de archivos binarios precompilados para conocer todos los objetivos de soporte de primera clase.
cargo
La forma más sencilla de instalar es mediante cargo
.
$ cargo install rsonpath
...
Si la velocidad máxima es primordial, debe instalar rsonpath
con soporte nativo de instrucciones de CPU. Esto dará como resultado un binario que no es portátil y podría funcionar incorrectamente en cualquier otra máquina, pero exprimirá hasta el último bit de rendimiento.
Para hacer esto, ejecute la siguiente variante cargo install
:
$ RUSTFLAGS= " -C target-cpu=native " cargo install rsonpath
...
Consulte el capítulo correspondiente en el libro de registro.
El proyecto se desarrolla activamente y actualmente solo admite un subconjunto del lenguaje de consulta JSONPath. Una consulta es una secuencia de segmentos, cada uno de los cuales contiene uno o más selectores.
Segmento | Sintaxis | Apoyado | Desde | Problema de seguimiento |
---|---|---|---|---|
Segmento infantil (único) | [<selector>] | ✔️ | v0.1.0 | |
Segmento infantil (múltiple) | [<selector1>,...,<selectorN>] | |||
Segmento descendiente (único) | ..[<selector>] | ✔️ | v0.1.0 | |
Segmento descendiente (múltiple) | ..[<selector1>,...,<selectorN>] |
Selector | Sintaxis | Apoyado | Desde | Problema de seguimiento |
---|---|---|---|---|
Raíz | $ | ✔️ | v0.1.0 | |
Nombre | .<member> , [<member>] | ✔️ | v0.1.0 | |
Comodín | .* , ..* , [*] | ✔️ | v0.4.0 | |
Índice (índice de matriz) | [<index>] | ✔️ | v0.5.0 | |
Índice (índice de matriz desde el final) | [-<index>] | |||
Corte de matriz (hacia adelante, límites positivos) | [<start>:<end>:<step>] | ✔️ | v0.9.0 | #152 |
Corte de matriz (límites arbitrarios hacia adelante) | [<start>:<end>:<step>] | |||
Corte de matriz (hacia atrás, límites arbitrarios) | [<start>:<end>:-<step>] | |||
Filtros – pruebas existenciales | [?<path>] | #154 | ||
Filtros: comparaciones de átomos constantes | [?<path> <binop> <atom>] | #156 | ||
Filtros – expresiones lógicas | && , || , ! | |||
Filtros – anidamiento | [?<expr>[?<expr>]...] | |||
Filtros: comparaciones arbitrarias | [?<path> <binop> <path>] | |||
Filtros – extensiones de funciones | [?func(<path>)] |
La caja se construye continuamente para todos los objetivos de Rust de nivel 1 y se ejecutan pruebas continuamente para objetivos que se pueden ejecutar con imágenes de acción de GitHub. SIMD solo se admite en plataformas x86/x86_64.
triple objetivo | construir nosimd | soporte SIMD | Pruebas continuas | Problemas de seguimiento |
---|---|---|---|---|
aarch64-desconocido-linux-gnu | ✔️ | ✔️ | #21, #115 | |
i686-desconocido-linux-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-desconocido-linux-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-manzana-darwin | ✔️ | ✔️ | ✔️ | |
i686-pc-windows-gnu | ✔️ | ✔️ | ✔️ | |
i686-pc-windows-msvc | ✔️ | ✔️ | ✔️ | |
x86_64-pc-windows-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-pc-windows-msvc | ✔️ | ✔️ | ✔️ |
La compatibilidad con SIMD se habilita módulo por módulo. Generalmente, cualquier CPU lanzada en la última década es compatible con AVX2, que permite todas las optimizaciones disponibles.
Las CPU más antiguas con SSE2 o superior obtienen soporte parcial. Puede verificar qué está habilitado exactamente con rq --version
; verifique el campo SIMD support
:
$ 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_popcnt
La capacidad fast_quotes
depende de la instrucción pclmulqdq
y fast_popcnt
de la instrucción popcnt
.
No todos los selectores son compatibles; consulte la tabla de compatibilidad anterior.
El motor supone que cada objeto en el JSON de entrada no tiene claves duplicadas. No se garantiza que el comportamiento de las claves duplicadas sea estable, pero actualmente el motor simplemente coincidirá con la primera clave de este tipo.
$ rq ' $.key ' --json ' {"key":"value","key":"other value"} '
"value"
El motor no analiza secuencias de escape Unicode en los nombres de los miembros. Esto significa que una clave "a"
es diferente de una clave "u0041"
, aunque semánticamente representan la misma cadena. En realidad, esto está diseñado con respecto a la especificación JSONPath actual. El análisis de secuencias Unicode es costoso, por lo que se pospuso el soporte para esto en favor del alto rendimiento. Esto se rastrea como #117.
La esencia es: bifurcar, implementar, hacer un PR aquí. Más detalles están en el documento CONTRIBUYENTE.
El flujo de trabajo de desarrollo utiliza just
. Utilice el Justfile
incluido. Instalará Rust automáticamente utilizando la herramienta rustup
si detecta que no hay Cargo en su entorno.
$ just build
...
$ just test
...
Los puntos de referencia para rsonpath
se encuentran en un repositorio separado, incluido como un submódulo git en este repositorio principal.
La forma más sencilla de ejecutar todos los puntos de referencia es just bench
. Para obtener más información, consulte el archivo README en el submódulo.
¡Tenemos un artículo sobre rsonpath
que se publicará en ASPLOS '24! Puedes leerlo aquí.
Este proyecto fue concebido como mi tesis. Puede leerlo para obtener detalles sobre los antecedentes teóricos del motor y detalles de su implementación.
Mostrando dependencias directas; para ver el gráfico completo, consulte a continuación.
cargo tree --package rsonpath --edges normal --depth 1
rsonpath v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath)
├── clap v4.5.4
├── color-eyre v0.6.3
├── eyre v0.6.12
├── log v0.4.21
├── rsonpath-lib v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
└── simple_logger v4.3.3
[build-dependencies]
├── rustflags v0.1.5
└── vergen v8.3.1
[build-dependencies]
cargo tree --package rsonpath-lib --edges normal --depth 1
rsonpath-lib v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
├── arbitrary v1.3.2
├── cfg-if v1.0.0
├── log v0.4.21
├── memmap2 v0.9.4
├── nom v7.1.3
├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
├── smallvec v1.13.2
├── static_assertions v1.1.0
├── thiserror v1.0.58
└── vector-map v1.0.1
clap
: caja estándar para proporcionar la CLI.color-eyre
, eyre
: mensajes de error más accesibles para el analizador.log
, simple-logger
: registros de diagnóstico durante la compilación y ejecución.cfg-if
: se utiliza para admitir versiones SIMD y no SIMD.memmap2
: para una lectura rápida de archivos fuente a través de un mapa de memoria en lugar de copias almacenadas en el buffer.nom
– para la implementación del analizador.smallvec
: crucial para el rendimiento de pilas pequeñas.static_assertions
: confiabilidad adicional mediante algunas suposiciones constantes validadas en el momento de la compilación.thiserror
: implementaciones Error
idiomáticos.vector_map
: utilizado en el compilador de consultas para un rendimiento considerablemente mejor. cargo tree --package rsonpath --edges normal
rsonpath v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath)
├── clap v4.5.4
│ ├── clap_builder v4.5.2
│ │ ├── anstream v0.6.13
│ │ │ ├── anstyle v1.0.6
│ │ │ ├── anstyle-parse v0.2.3
│ │ │ │ └── utf8parse v0.2.1
│ │ │ ├── anstyle-query v1.0.2
│ │ │ │ └── windows-sys v0.52.0
│ │ │ │ └── windows-targets v0.52.4
│ │ │ │ ├── windows_aarch64_gnullvm v0.52.4
│ │ │ │ ├── windows_aarch64_msvc v0.52.4
│ │ │ │ ├── windows_i686_gnu v0.52.4
│ │ │ │ ├── windows_i686_msvc v0.52.4
│ │ │ │ ├── windows_x86_64_gnu v0.52.4
│ │ │ │ ├── windows_x86_64_gnullvm v0.52.4
│ │ │ │ └── windows_x86_64_msvc v0.52.4
│ │ │ ├── anstyle-wincon v3.0.2
│ │ │ │ ├── anstyle v1.0.6
│ │ │ │ └── windows-sys v0.52.0 (*)
│ │ │ ├── colorchoice v1.0.0
│ │ │ └── utf8parse v0.2.1
│ │ ├── anstyle v1.0.6
│ │ ├── clap_lex v0.7.0
│ │ ├── strsim v0.11.1
│ │ └── terminal_size v0.3.0
│ │ ├── rustix v0.38.32
│ │ │ ├── bitflags v2.5.0
│ │ │ ├── errno v0.3.8
│ │ │ │ ├── libc v0.2.153
│ │ │ │ └── windows-sys v0.52.0 (*)
│ │ │ ├── libc v0.2.153
│ │ │ ├── linux-raw-sys v0.4.13
│ │ │ └── windows-sys v0.52.0 (*)
│ │ └── windows-sys v0.48.0
│ │ └── windows-targets v0.48.5
│ │ ├── windows_aarch64_gnullvm v0.48.5
│ │ ├── windows_aarch64_msvc v0.48.5
│ │ ├── windows_i686_gnu v0.48.5
│ │ ├── windows_i686_msvc v0.48.5
│ │ ├── windows_x86_64_gnu v0.48.5
│ │ ├── windows_x86_64_gnullvm v0.48.5
│ │ └── windows_x86_64_msvc v0.48.5
│ └── clap_derive v4.5.4 (proc-macro)
│ ├── heck v0.5.0
│ ├── proc-macro2 v1.0.79
│ │ └── unicode-ident v1.0.12
│ ├── quote v1.0.35
│ │ └── proc-macro2 v1.0.79 (*)
│ └── syn v2.0.58
│ ├── proc-macro2 v1.0.79 (*)
│ ├── quote v1.0.35 (*)
│ └── unicode-ident v1.0.12
├── color-eyre v0.6.3
│ ├── backtrace v0.3.71
│ │ ├── addr2line v0.21.0
│ │ │ └── gimli v0.28.1
│ │ ├── cfg-if v1.0.0
│ │ ├── libc v0.2.153
│ │ ├── miniz_oxide v0.7.2
│ │ │ └── adler v1.0.2
│ │ ├── object v0.32.2
│ │ │ └── memchr v2.7.2
│ │ └── rustc-demangle v0.1.23
│ │ [build-dependencies]
│ │ └── cc v1.0.90
│ ├── eyre v0.6.12
│ │ ├── indenter v0.3.3
│ │ └── once_cell v1.19.0
│ ├── indenter v0.3.3
│ ├── once_cell v1.19.0
│ └── owo-colors v3.5.0
├── eyre v0.6.12 (*)
├── log v0.4.21
├── rsonpath-lib v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
│ ├── cfg-if v1.0.0
│ ├── log v0.4.21
│ ├── memmap2 v0.9.4
│ │ └── libc v0.2.153
│ ├── nom v7.1.3
│ │ ├── memchr v2.7.2
│ │ └── minimal-lexical v0.2.1
│ ├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
│ │ ├── nom v7.1.3 (*)
│ │ ├── owo-colors v4.0.0
│ │ ├── thiserror v1.0.58
│ │ │ └── thiserror-impl v1.0.58 (proc-macro)
│ │ │ ├── proc-macro2 v1.0.79 (*)
│ │ │ ├── quote v1.0.35 (*)
│ │ │ └── syn v2.0.58 (*)
│ │ └── unicode-width v0.1.11
│ ├── smallvec v1.13.2
│ ├── static_assertions v1.1.0
│ ├── thiserror v1.0.58 (*)
│ └── vector-map v1.0.1
│ ├── contracts v0.4.0 (proc-macro)
│ │ ├── proc-macro2 v1.0.79 (*)
│ │ ├── quote v1.0.35 (*)
│ │ └── syn v1.0.109
│ │ ├── proc-macro2 v1.0.79 (*)
│ │ ├── quote v1.0.35 (*)
│ │ └── unicode-ident v1.0.12
│ └── rand v0.7.3
│ ├── getrandom v0.1.16
│ │ ├── cfg-if v1.0.0
│ │ ├── libc v0.2.153
│ │ └── wasi v0.9.0+wasi-snapshot-preview1
│ ├── libc v0.2.153
│ ├── rand_chacha v0.2.2
│ │ ├── ppv-lite86 v0.2.17
│ │ └── rand_core v0.5.1
│ │ └── getrandom v0.1.16 (*)
│ ├── rand_core v0.5.1 (*)
│ └── rand_hc v0.2.0
│ └── rand_core v0.5.1 (*)
├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax) (*)
└── simple_logger v4.3.3
├── colored v2.1.0
│ ├── lazy_static v1.4.0
│ └── windows-sys v0.48.0 (*)
├── log v0.4.21
├── time v0.3.34
│ ├── deranged v0.3.11
│ │ └── powerfmt v0.2.0
│ ├── itoa v1.0.11
│ ├── libc v0.2.153
│ ├── num-conv v0.1.0
│ ├── num_threads v0.1.7
│ │ └── libc v0.2.153
│ ├── powerfmt v0.2.0
│ ├── time-core v0.1.2
│ └── time-macros v0.2.17 (proc-macro)
│ ├── num-conv v0.1.0
│ └── time-core v0.1.2
└── windows-sys v0.48.0 (*)
[build-dependencies]
├── rustflags v0.1.5
└── vergen v8.3.1
├── anyhow v1.0.81
├── cargo_metadata v0.18.1
│ ├── camino v1.1.6
│ │ └── serde v1.0.197
│ │ └── serde_derive v1.0.197 (proc-macro)
│ │ ├── proc-macro2 v1.0.79 (*)
│ │ ├── quote v1.0.35 (*)
│ │ └── syn v2.0.58 (*)
│ ├── cargo-platform v0.1.8
│ │ └── serde v1.0.197 (*)
│ ├── semver v1.0.22
│ │ └── serde v1.0.197 (*)
│ ├── serde v1.0.197 (*)
│ ├── serde_json v1.0.115
│ │ ├── itoa v1.0.11
│ │ ├── ryu v1.0.17
│ │ └── serde v1.0.197 (*)
│ └── thiserror v1.0.58 (*)
├── cfg-if v1.0.0
├── regex v1.10.4
│ ├── aho-corasick v1.1.3
│ │ └── memchr v2.7.2
│ ├── memchr v2.7.2
│ ├── regex-automata v0.4.6
│ │ ├── aho-corasick v1.1.3 (*)
│ │ ├── memchr v2.7.2
│ │ └── regex-syntax v0.8.3
│ └── regex-syntax v0.8.3
├── rustc_version v0.4.0
│ └── semver v1.0.22 (*)
└── time v0.3.34
├── deranged v0.3.11 (*)
├── itoa v1.0.11
├── libc v0.2.153
├── num-conv v0.1.0
├── num_threads v0.1.7 (*)
├── powerfmt v0.2.0
└── time-core v0.1.2
[build-dependencies]
└── rustversion v1.0.14 (proc-macro)