# QUERY Expressions

This page explains how `QUERY` filters JSON documents by field, its expression grammar, and how to build the same filters in Go.

## QUERY

```text
QUERY active = true
QUERY profile.level >= 3
QUERY role = admin AND active = true LIMIT 20
QUERY (role = admin OR role = editor) AND NOT disabled = true
```

Only JSON entries with a warm parsed cache are evaluated. A condition reads a dot-notation field, renders it with `utils.Vtoa` (so `1.0` becomes `1` and `true` stays `true`), and compares it with the operator. A missing field makes the condition false, including under `NE`.

Each result line is `key: <raw JSON>`, not just the key.

## Expression Grammar

```text
expression := or
or         := and ( OR and )*
and        := not ( AND not )*
not        := NOT not | primary
primary    := "(" expression ")" | field operator value
```

- `AND`, `OR`, and `NOT` are case-insensitive; `AND` binds tighter than `OR`.
- Input is split on whitespace, then leading `(` and trailing `)` are peeled off each token, so `(role` and `editor)` work.
- A value is one token; it cannot contain spaces.
- Leftover tokens fail with `unexpected word: ...`; a missing operator, value, or `)` also fails.

## Programmatic Filters

```go
f := filter.And{
    filter.GTE{Field: "profile.level", Value: "3"},
    filter.Not{filter.EQ{Field: "disabled", Value: "true"}},
}
rows := torii.Query(f, 20)

parsed, err := filter.AtoFilter("role = admin OR role = editor")
```

| Type | Kind |
|---|---|
| `And`, `Or` | `[]Filter` |
| `Not` | `[1]Filter` |
| `Cond{Field, Op, Value}` | Generic condition |
| `EQ`, `NE`, `GT`, `GTE`, `GE`, `LT`, `LTE`, `LE`, `LIKE` | `{Field, Value}` shorthands |

## Related Pages

- [Operators and FIND](/querying-operators)
- [JSON Documents](/json-documents)
- [filter](/api-reference-filter)
