JSONiq: JSON Query Language
jsoniq.org
jsoniq.org
> Queries are 80% shorter than imperative code
From the examples they look the same length as the corresponding JS I would write, maybe slightly longer.
What are the advantages to using this language over JS?
JS has a fast JIT which would make filtering data fast. How does this query language compare in performance? Does it have indexes?
Just like how you could easily manipulate tabular data using numpy or pandas (or excel), but SQL allows you to do it declaratively, which has benefits in some cases.
The motivation for JSONiq and RumbleDB is discussed in this recent paper, the core argument is data independence:
https://arxiv.org/abs/1910.11582v3
JSONiq is a functional language and thus makes it easy to scale to collections that have billions of objects.
A notable difference with JavaScript is that JSONiq has the FLWOR expression, which is similar to, but more generic than, a SQL statement.
Maybe I'm misunderstanding something, but isn't SQL perfectly capable of acting on denormalized data? We often talk about the degree of normalization that a RDMS has. Perhaps this is in reference to nested data structures (which would normally be represented in RDMS via FK relations), but even there it's implementation dependent.
If you have nested data structures then it violates 1NF, i.e. the data isn't normalised.
Any "pure" RDBMS won't even be able to represent that denormalised data in a table, let alone query it with SQL. Normally this is worked around by straight up serialising it. Obviously some implementations have extensions, like Postgres has JSON columns.
SQL databases do indeed work with data not in Boyce-Codd-Normal-Form. :D
There exist indeed recent extensions of SQL that add support for denormalized data (arrays, objects), for example in Spark SQL and PostgreSQL, however SQL was originally designed for tables and it remains cumbersome to write complex queries on denormalized data (lateral views, etc).
A deeper and more detailed analysis of query languages for nested data can be found in our recent paper with a concrete use case in high energy physics, to be presented at VLDB 2022:
* RFC 6901 JavaScript Object Notation (JSON) Pointer: https://datatracker.ietf.org/doc/html/rfc6901
* JSONPath RFC Draft: https://www.rfc-editor.org/rfc/internet-drafts/draft-ietf-js...
* jq utility query language: https://stedolan.github.io/jq/manual/
* GROQ: https://groq.dev
https://github.com/ghislainfourny/jsoniq-tutorial
Back button.
https://colab.research.google.com/github/RumbleDB/rumble/blo...
The easiest way to get started locally is described here: https://rumble.readthedocs.io/en/latest/Getting%20started/
We no longer recommend the installation of Anaconda -- instead, the Spark tgz file can directly be downloaded, unzipped, and the bin subdirectory added to the PATH, which is considerably simpler. Likewise, the RumbleDB jar is just a download. Using the RumbleDB shell is the easiest to set up; Jupyter and the server require a bit of additional work.
For a cluster, this is even easier because most cloud platforms can create one with the push of a button, and one only needs to download the RumbleDB jar on the remote machine and get started right away.
Use of RumbleDB on a cluster is explained here: https://rumble.readthedocs.io/en/latest/Run%20on%20a%20clust...
Another thing is that it supposedly can scale to absolutely massive datasets, since there is a Rumbe/Hadoop backend.
Structuring data is an art and a skill. Perhaps not taught very well.
There is a low-cost solution: CSV, TSV, lines of text.
The high-cost solution is relational structure and servers.
In the middle range, with risk of expensive tooling and glaring anti-patterns, are XML and JSON.
The latter can both be used simply or with grotesque opacity. A some point, feeding the monster becomes a main activity of the village. At which point, the villagers elect a new monster with their shovels and pitchforks.
JSONiq is strongly typed, so only the strongly typed languages are equivalent.
The point of this project, like SQL, is to have something programming language agnostic that can be understood and optimized by a db or a tool that doesn’t use your programming language.
It’s mostly designed for data analysis and data interchange.
First, from [1]:
... two representative [JSON] transformation tasks are considered ... The exercise demonstrates that the absence of parent or ancestor axes in the native representation of JSON means that the transformation task needs to be approached in a very different way.
The article shows that the ability to "navigate upward" to the parent of a node can make certain queries and transformation easier to implement. BTW, as far as I can tell, JSONIq does not provide a way to "navigate upward" ...
But! also from [1]:
The ability to navigate upwards (and to a lesser extent, sideways, to preceding and following siblings) clearly has advantages and disadvantages. Without upwards navigation, a transformation process that operates primarily as a recursive tree walk cannot discover the context of leaf nodes (for example, when processing a price, what product does it relate to?), so this information needs to be passed down in the form of parameters. However, the convenience of being able to determine the context of a node comes at a significant price.
I remember dealing with trees in pure functional languages and finding that typically implementing parent pointers can be tricky [2]. I think if we combine this two facts, we can see that not all languages make the same query or transformation tasks equally easy.
1: Page 167 of https://archive.xmlprague.cz/2016/files/xmlprague-2016-proce...
https://github.com/sirixdb/sirix
The query engine used is developed here (core implemented by Sebastian Bächle and his tudents). Ideally the backend can be any other data store as well.
1. let $stats := collection("stats")
2. for $access in $stats
3. group by $url := $access.url
4. return
5. {
6. "url": $url,
7. "avg": avg($access.response_time),
8. "hits": count($access)
9. }So basically grep or even sql ->xquery. No thank you!
$ jq '.foo += 1' <<< '{"foo": 2}'
{
"foo": 3
}But we have a function: https://github.com/sirixdb/brackit
def avg: add / length;
group_by(.url) | map({
"url": .[0].url,
"hits": length,
"avg": map(.response_time) | avg
})
so jq should be (at least roughly) as powerful as JSONiq.Likewise, compare "sum($element.response_time)" with "map(.response_time) | add" in jq. Processing in JSONiq goes inside to outside while jq goes left to right.
Jq works, both in python, and from the shell prompt. https://pypi.org/project/jq/
They missed a huge opportunity to call it FLOWR (flow-er as in one who flows, or flower as in the thing that grows).
- https://en.wikipedia.org/wiki/FLWOR
- https://www.w3.org/TR/xquery-30/#id-flwor-expressions
FLWOR is pronounced 'flower'.
let €gdpr = 42;
let £colour = #B0B;
There, this is more compelling, isn't it?
let ¤whatever = 123;
was invented instead.From [1]:
XQuery 3.1 was designed with the goal to support additional data structures (maps, arrays) in memory. These structures are mapped to JSON for input and output. XQuery 3.1 has been a W3C recommendation since March 2017.
JSONiq was designed with the goal of querying and updating JSON in settings such as document stores. It was also designed by members of the XML Query working group (disclaimer: I am one of them) while investigating various possibilities to support JSON.
1: https://stackoverflow.com/questions/44919443/what-are-the-di...
https://github.com/sirixdb/brackit
for instance :)
This is, in fact, not an assignment, but a variable binding that is highly optimizable by an execution engine. The let clause is part of the FLWOR expression, works in orchestration with for, where, group by, order by, count, return; the ability to bind variables while doing relational algebra is a feature that is often missed in SQL.
JSONiq is functional and, in its core (non scripting) version, does not allow modifying variable values.