# What can we still query once it's encrypted?

*Published on 2026-10-13T00:00:00.000Z*

*By CipherStash Team*

Four families. Equality (=, IN, GROUP BY, joins), text match, ordering and range (ORDER BY, BETWEEN, MIN and MAX), and JSON containment, path queries and ordering on leaves. Each is an index type you opt into per column. SUM, AVG, regex and LIKE do not work on ciphertext, and the docs say so.

## Content

You will not get everything. Anything that needs the database to do arithmetic on the value is out, and so is any pattern language richer than approximate text matching. What you do get covers most of what application code asks a database for, and each capability is a column-level choice that costs storage and leaks a little, so you turn it on only where you need it.

## Equality

`=`, `<>`, `IN` (including `IN (subquery)`), `DISTINCT` and equijoins all work on an equality-capable column. The term is an HMAC-SHA-256 of the value, so two rows with the same plaintext share a term. That is what makes equality work, and it is also what leaks.

Two rules from the docs are worth knowing before you ship. `GROUP BY` must be written as `GROUP BY eql_v3.eq_term(col)`. A bare `GROUP BY col` runs and returns wrong groups. And both sides of a join must be encrypted under the same keyset and typed as a matching variant, or the join returns no rows without an error.

## Text match

The `@@` operator does probabilistic n-gram bloom matching. The value is downcased, split into 3-grams, and hashed into a bloom filter. A query is the same transform on the needle, then array containment. Matching is case-insensitive, the needle must be at least 3 characters, a `true` can be a false positive and a `false` is never a false negative. `LIKE`, `ILIKE` and regex raise on encrypted columns. If your product needs ranked full-text search, this is not that.

## Ordering and range

`<`, `<=`, `>`, `>=`, `BETWEEN`, `ORDER BY`, `MIN` and `MAX` work on an ordered column, plus equality. The default term is CLLW order-preserving encryption, which indexes with a plain `bytea_ops` class anywhere you can `CREATE INDEX`. Block ORE is available as a pinned alternative where you have superuser. `ORDER BY` on a column that was not given an ordering index does not error. The order is meaningless.

## JSON

An encrypted JSON column supports containment (`@>`, `<@`), field access (`->`, `->>`), `jsonb_path_query`, `jsonb_path_exists`, array length and elements, and range and `ORDER BY` on string and number leaves. Fields are addressed by a selector hash rather than a plaintext path. Key-existence operators, concatenation, deletion and equality on the root document are blocked, and extracted leaves cannot be grouped by equality.

## What is refused, on purpose

`SUM`, `AVG` and every other arithmetic aggregate. The docs put it plainly: those would require homomorphic encryption, which EQL does not do. `COUNT` and `COUNT(DISTINCT eql_v3.eq_term(...))` are fine.

## Technical evidence

- [EQL core concepts: variants and terms](/docs/reference/eql/core-concepts)
- [Filtering](/docs/reference/eql/filtering)
- [Text match](/docs/reference/eql/text)
- [Sorting](/docs/reference/eql/sorting)
- [Joins](/docs/reference/eql/joins)
- [Grouping and aggregates](/docs/reference/eql/grouping-and-aggregates)
- [JSON](/docs/reference/eql/json)
- [Searchable encryption: what leaks](/docs/concepts/searchable-encryption)

## Related notes

- [Is this Postgres only?](https://cipherstash.com/notes/is-this-postgres-only.md) — For searchable encryption, yes. Any Postgres you can connect to, no extension and no superuser. DynamoDB gets equality lookups. Everything else gets encryption without server-side queries.
- [If it's searchable, how encrypted is it really?](https://cipherstash.com/notes/if-its-searchable-how-encrypted-is-it-really.md) — Less than an opaque blob. Each search term reveals something specific, and the docs list what. Search is optional per column, and a column without it reveals nothing beyond the ciphertext.

