Where Operators
Complete reference of all query operators in the where sub-package.
Import: github.com/oliverandrich/den/where
Usage
import "github.com/oliverandrich/den/where"
// Single condition
results, err := den.NewQuery[Product](db,
where.Field("price").Gt(10.0),
).All(ctx)
// Multiple conditions (implicit AND)
results, err := den.NewQuery[Product](db,
where.Field("price").Gte(10),
where.Field("category").Eq("Electronics"),
).All(ctx)
// Nested field access via dot notation
results, err := den.NewQuery[Product](db,
where.Field("address.city").Eq("Berlin"),
).All(ctx)
Comparison Operators
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
Eq |
Field("name").Eq("Widget") |
Equal to value |
json_extract(data, '$.name') = ? |
data->>'name' = $1 |
Ne |
Field("status").Ne("deleted") |
Not equal to value |
json_extract(data, '$.status') != ? |
data->>'status' != $1 |
Gt |
Field("price").Gt(10) |
Greater than value |
json_extract(data, '$.price') > ? |
(data->>'price')::float > $1 |
Gte |
Field("price").Gte(10) |
Greater than or equal |
json_extract(data, '$.price') >= ? |
(data->>'price')::float >= $1 |
Lt |
Field("price").Lt(100) |
Less than value |
json_extract(data, '$.price') < ? |
(data->>'price')::float < $1 |
Lte |
Field("price").Lte(100) |
Less than or equal |
json_extract(data, '$.price') <= ? |
(data->>'price')::float <= $1 |
Null Operators
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
IsNil |
Field("read_at").IsNil() |
Field is null / not set |
json_extract(data, '$.read_at') IS NULL |
data->>'read_at' IS NULL |
IsNotNil |
Field("read_at").IsNotNil() |
Field is not null |
json_extract(data, '$.read_at') IS NOT NULL |
data->>'read_at' IS NOT NULL |
Set Operators
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
In |
Field("status").In("active", "pending") |
Value is one of the given values |
json_extract(data, '$.status') IN (?, ?) |
data->>'status' = ANY($1) |
NotIn |
Field("status").NotIn("deleted", "banned") |
Value is not one of the given values |
json_extract(data, '$.status') NOT IN (?, ?) |
data->>'status' != ALL($1) |
Spreading typed slices into In / NotIn
Both methods are variadic over any. Passing a typed slice directly silently matches against the literal slice value rather than its elements — common footgun. Use where.AnyOf[T] to convert and spread:
ids := []string{"a", "b", "c"}
where.Field("id").In(where.AnyOf(ids)...)
where.Field("status").NotIn(where.AnyOf(allClosedStatuses)...)
Type inference picks T from the argument; no explicit type parameter needed.
Array Operators
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
Contains |
Field("tags").Contains("golang") |
Array contains the value |
EXISTS (SELECT 1 FROM json_each(...) WHERE value = ?) |
data->'tags' @> '["golang"]'::jsonb |
ContainsAny |
Field("tags").ContainsAny("go", "rust") |
Array contains any of the values |
Multiple EXISTS with OR |
data->'tags' ?| array[...] |
ContainsAll |
Field("tags").ContainsAll("go", "web") |
Array contains all of the values |
Multiple EXISTS with AND |
data->'tags' @> '[...]'::jsonb |
Map / Object Operators
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
HasKey |
Field("metadata").HasKey("color") |
Map/object contains the given key |
json_extract(data, '$.metadata.color') IS NOT NULL |
data->'metadata' ? 'color' |
String Operators
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
StringContains |
Field("name").StringContains("alpha") |
Field contains the substring |
json_extract(data, '$.name') LIKE '%alpha%' ESCAPE '\' |
data->>'name' ILIKE '%alpha%' |
StartsWith |
Field("name").StartsWith("Al") |
Field starts with the prefix |
json_extract(data, '$.name') LIKE 'Al%' ESCAPE '\' |
data->>'name' ILIKE 'Al%' |
EndsWith |
Field("name").EndsWith("ta") |
Field ends with the suffix |
json_extract(data, '$.name') LIKE '%ta' ESCAPE '\' |
data->>'name' ILIKE '%ta' |
Note: String operators automatically escape special SQL characters (%, _, \) in the search term.
Pattern Matching
| Operator |
Example |
Description |
SQLite |
PostgreSQL |
RegExp |
Field("name").RegExp("^W.+t$") |
Match field against a regular expression |
json_extract(data, '$.name') REGEXP ? |
data->>'name' ~ $1 |
Logical Operators
Logical operators compose multiple conditions.
| Operator |
Example |
Description |
And |
where.And(cond1, cond2, ...) |
All conditions must match |
Or |
where.Or(cond1, cond2, ...) |
At least one condition must match |
Not |
where.Not(cond) |
Negate a condition |
Examples
// AND: price between 10 and 100
results, err := den.NewQuery[Product](db,
where.And(
where.Field("price").Gt(10),
where.Field("price").Lt(100),
),
).All(ctx)
// OR: active or featured
results, err := den.NewQuery[Product](db,
where.Or(
where.Field("status").Eq("active"),
where.Field("featured").Eq(true),
),
).All(ctx)
// NOT: exclude deleted
results, err := den.NewQuery[Product](db,
where.Not(where.Field("deleted").Eq(true)),
).All(ctx)
// Combined
results, err := den.NewQuery[Product](db,
where.And(
where.Field("price").Gte(10),
where.Or(
where.Field("category").Eq("Electronics"),
where.Field("featured").Eq(true),
),
),
).All(ctx)
Nested Fields
Use dot notation to access nested fields in embedded objects:
// Object field
where.Field("address.city").Eq("Berlin")
// Deeply nested
where.Field("category.parent.name").Eq("Root")
// Array index
where.Field("tags.0").Eq("featured")