NOTE: This query language is work in progress. Consider it experimental, suited for exploratory programming, but not suited for production usage yet (2019-08-04).
NOTE: In this document, the word list also applies to arrays and vectors.
The --query
option allows to select or remove specific parts of the output. A
query is written in EDN.
Single values can be selected by using a key:
echo '{:a 1}' | jet --from edn --to edn --query ':a'
1
or more explicity with get
:
echo '{:a 1}' | jet --from edn --to edn --query '(get :a)'
1
NOTE: in some places, queries can conflict with key names. E.g:
echo '{(juxt :a) 1}' | jet --from edn --to edn --query '(juxt :a)'
[nil]
In these places, get
offers an unambiguous way to retrieve the value:
$ echo '{(juxt :a) 1}' | jet --from edn --to edn --query '(get (juxt :a))'
1
Numbers can be used for looking up by position in lists:
$ echo '[1 2 3]' | lein jet --from edn --to edn --query '0'
1
$ echo '[1 2 3]' | lein jet --from edn --to edn --query '100'
nil
A subselection of a map can be made with select-keys
:
echo '{:a 1 :b 2 :c 3}' | jet --from edn --to edn --query '(select-keys :a :b)'
{:a 1, :b 2}
NOTE: unlike in Clojure, the keys for select-keys
are not wrapped in a
sequence.
Removing keys can be achieved with dissoc
:
echo '{:a 1 :b 2 :c 3}' | jet --from edn --to edn --query '(dissoc :c)'
{:a 1, :b 2}
A query can be applied to every element in a list using map
:
$ echo '[{:a 1 :b 2} {:a 2 :b 3}]' | jet --from edn --to edn --query '(map (select-keys :a))'
[{:a 1} {:a 2}]
Associating a new key and value in a map is done with assoc
:
$ echo '{:a 1}' | jet --from edn --to edn --query '(assoc :b :a)'
{:a 1, :b 1}
Updating an existing key and value can be done with update
:
$ echo '{:a {:b 1}}' | jet --from edn --to edn --query '(update :a :b)'
{:a 1}
echo '{:a [1 2 3]}' | jet --from edn --to edn --query '(update :a (take 2))'
{:a [1 2]}
echo '{:a [1 2 3]}' | jet --from edn --to edn --query '(update :a (drop 2))'
{:a [3]}
echo '{:a [1 2 3]}' | jet --from edn --to edn --query '(update :a (nth 2))'
{:a 3}
The difference between assoc
and update
is that the query provided to the
former begins at the root and the query provided to the latter begins at place
to be updated.
There are also assoc-in
and update-in
which behave in similar ways but allow
changing nested values:
$ echo '{:a 1}' | lein jet --from edn --to edn --query '(assoc-in [:b :c] :a)'
{:a 1, :b {:c 1}}
$ echo '{:a {:b [1 2 3]}}' | lein jet --from edn --to edn --query '(update-in [:a :b] last)'
{:a {:b 3}}
Creating a new map from scratch is done with hash-map
:
$ echo '{:a 1 :b 2}' | jet --from edn --to edn --query '(hash-map :foo :a :bar :b)'
{:foo 1, :bar 2}
and creating new values from scratch is done with quote
:
$ echo '{:a 1}' | jet --from edn --to edn --query '(hash-map :foo :a :bar (quote "hello"))'
{:foo 1, :bar "hello"}
Applying multiple queries after one another can be achieved using vector notation.
$ echo '{:a {:a/a 1 :a/b 2} :b 2}' | jet --from edn --to edn --query '[(select-keys :a) (update :a :a/a)]'
{:a 1}
In addition to the functions we've already covered, these Clojure-like functions are supported:
assoc
, assoc-in
, update
, update-in
,
keys
, vals
, rename-keys
, select-keys
, dissoc
, map-vals
, juxt
,
count
.first
, last
, take
, drop
, nth
,
map
, zipmap
, filter
, remove
, juxt
, count
, distinct
, dedupe
.quote
.$ echo '{:a [1 2 3] :b [4 5 6]}' | jet --from edn --to edn --query '(keys)'
[:a :b]
$ echo '{:a [1 2 3] :b [4 5 6]}' | jet --from edn --to edn --query '(vals)'
[[1 2 3] [4 5 6]]
echo '{"foo bar": 1}' | jet --from json --to json --query '(rename-keys {"foo bar" "foo-bar"})'
{"foo-bar":1}
echo '[1 2 3]' | jet --from edn --to edn --query '(first)'
1
echo '[1 2 3]' | jet --from edn --to edn --query '(last)'
3
echo '[[1 2 3] [4 5 6]]' | jet --from edn --to edn --query '(last)'
[4 5 6]
echo '[[1 2 3] [4 5 6]]' | jet --from edn --to edn --query '(map last)'
[3 6]
echo '[{:a 1} {:a 2}]' | jet --from edn --to edn --query '(count)'
2
echo '[{:a 1} {:a 2}]' | jet --from edn --to edn --query '(map count)'
[1 1]
To apply a function on a all map values, use map-vals
:
$ echo '{:foo {:a 1 :b 2} :bar {:a 1 :b 2}}' | jet --from edn --to edn --query '(map-vals :a)'
{:foo 1 :bar 2}
Use juxt
to apply multiple queries to the same element. The result is a list
of multiple results.
$ echo '{:a [1 2 3] :b [4 5 6]}' | jet --from edn --to edn --query '(juxt :a :b)'
[[1 2 3] [4 5 6]]
$ echo '{:a [1 2 3]}' | jet --from edn --to edn --query '(update :a (juxt first last))'
{:a [1 3]}
$ echo '[1 2 3]' | jet --from edn --to edn --query '(juxt 0 1 2 3)'
[1 2 3 nil]
An example with zipmap
:
$ echo '{:keys [:a :b :c] :vals [1 2 3]}' \
| jet --from edn --to edn --query '[(juxt :keys :vals) (zipmap)]'
{:a 1, :b 2, :c 3}
Examples with filter
and remove
:
$ curl -s https://jsonplaceholder.typicode.com/todos \
| jet --from json --keywordize --to edn --query '[(filter :completed) (count)]'
90
$ curl -s https://jsonplaceholder.typicode.com/todos \
| jet --from json --keywordize --to edn --query '[(remove :completed) (count)]'
110
Remove duplicate values with distinct
and dedupe
:
$ echo '{:a [1 1 2 2 3 3 1 1]}' | lein jet --from edn --to edn --query '[:a (distinct)]'
[1 2 3]
$ echo '{:a [1 1 2 2 3 3 1 1]}' | lein jet --from edn --to edn --query '[:a (dedupe)]'
[1 2 3 1]
Comparing values can be done with =
, not=
, >
, >=
, <
and <=
.
$ echo '[{:a 1} {:a 2} {:a 3}]' | jet --from edn --to edn --query '(filter (>= :a 2))'
[{:a 2} {:a 3}]
echo '[{:a {:b 1}} {:a {:b 2}}]' \
| jet --from edn --to edn --query '(filter (= [:a :b] 1))'
[{:a {:b 1}}]
The last example of the jq tutorial using jet:
$ curl -s 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | \
jet --from json --keywordize --to edn --pretty --query '
(map
{:message [:commit :message]
:name [:commit :committer :name]
:parents [:parents (map :html_url)]})'
({:message "Merge pull request #1948 from eli-schwartz/no-pacman-sy\n\ndocs: fix seriously dangerous download instructions for Arch Linux",
:name "GitHub",
...
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close