# Using JQ in PixieBrix

{% hint style="info" %}
New User? JavaScript is easier to learn and is now the preferred way to transform data in PixieBrix: [Using JavaScript in PixieBrix](/developing-mods/developer-concepts/transforming-data/using-javascript-in-pixiebrix.md)
{% endhint %}

## What is jq?

jq is a powerful expression language for filtering and transforming structured JSON data. It's available for the command line and [a variety of programming languages](https://github.com/stedolan/jq/wiki/FAQ#language-bindings), including Java, Python, and Javascript.

## Helpful Resources

* [jqplay: A playground for jq 1.6](https://jqplay.org/)
* [jq Manual](https://stedolan.github.io/jq/manual/): has runnable examples of each operator
* [jq Homepage](https://stedolan.github.io/jq/)
* [jq tag on StackOverflow](https://stackoverflow.com/questions/tagged/jq)

## Brick Arguments

The jq brick takes two input arguments:

* `data`: an object, array, or single value which is passed to jq
* `filter`: the jq "filter", which controls how to filter/transform the data

#### Brick Argument Examples

**Scenario #1: passing a variable for data**

You can pass a variable or template directly to data:

```yaml
id: "@pixiebrix/jq"
config:
  # @apiResult = {items: []}
  data: "@apiResult"
  filter: ".items"
```

**Scenario #2: passing multiple variables to data**

You can also pass multiple variables by passing a dictionary to data, including using template syntax:

```yaml
id: "@pixiebrix/jq"
config:
  data: 
    # @apiResult = {items: [{text: "foo"}]}
    result: "@apiResult"
    # @input = {query: "foo"}
    query: "{{ @input.query }}!"
  filter: ".query as $query | [.result.items[] | select(.text == $query)]"
```

## Common Pitfalls

* jq only has access to the data you passed in via the `data` argument. You should not use `@variable` syntax in the jq `filter`
* jq uses a `.` to refer to its input (the data you passed to the brick)
* jq can return multiple results. However, PixieBrix expects a single result from jq. Therefore, you must wrap an expression that returns multiple results in Array construction `[]` operator

## Filter Examples

**Creating a new object from the input**

▶️  [View on jqplay](https://jqplay.org/s/fDr44s8zoA)

```
{foo: 42, bar: .}
```

**Parsing and summing values**

▶️  [View on jqplay](https://jqplay.org/s/DGSZvfgt6a)

```
.transactions | map(.amount | capture("(?<val>\\\\d+) USD") | .val | tonumber) | add
```

**Filtering an array**

▶️  [View on jqplay](https://jqplay.org/s/L2GTYwQNqO)

Assign the query to a variable so you can use it in the `select` clause.

NOTE: jq's `select` operator returns multiple results. Wrap the expression in an Array Construction `[]` operator to return the results as a single array

```
.query as $query | [.items[] | select(.text == $query)]
```

**Looking up a value in a pre-defined map (Workshop Example)**

▶️  [View on jqplay](https://jqplay.org/s/w9fCJwgroD)

Pass the pre-defined map as an input to the jq brick. Then, assign the map to a variable (e.g., `$m`) so you can lookup up the value later in the filter:

```yaml
data:
  # ["A", "B", "C"]
  items: "@items"
  mapping:
    A: Alpha
    B: Bravo
    C: Charlie
filter: ".mapping as $m | .items | map($m[.])"
```

You can use jq's `//` defaulting operator to handle elements that aren't in the map. E.g.,

```yaml
filter: '.mapping as $m | .items | map($m[.] // "Unknown")'
```

**Writing multi-line expressions (Workshop Example)**

You can make long jq filters in the Workshop more readable by splitting them over multiple lines. To split a filter over multiple lines, use the `>-` YAML operator that replaces newlines with spaces, and strips off the last new line ([Read more about multi-line YAML strings](https://yaml-multiline.info/))

For example, to clean up the filter in the "Looking up a value in a pre-defined map" example above:

```yaml
filter: >-
  .mapping as $m |
  .items |
  map($m[.])
```

Multi-line expressions are also helpful for constructing objects with many properties. (Note that JQ requires parentheses around the object's values):

```yaml
filter: >-
  {
    fooCheck: (.foo > 42),
    barCheck: (.bar | length > 0),
  }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pixiebrix.com/developing-mods/developer-concepts/transforming-data/using-jq-in-pixiebrix.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
