@venizia/ignis-docs 0.2.0 → 0.2.1-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +24 -13
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +8 -4
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +247 -153
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +109 -323
- package/content/extensions/components/authentication/api.md +489 -602
- package/content/extensions/components/authentication/errors.md +135 -498
- package/content/extensions/components/authentication/index.md +89 -801
- package/content/extensions/components/authentication/usage.md +231 -955
- package/content/extensions/components/authorization/api.md +991 -644
- package/content/extensions/components/authorization/errors.md +204 -208
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +88 -795
- package/content/extensions/components/authorization/usage.md +219 -528
- package/content/extensions/components/health-check.md +77 -243
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +553 -285
- package/content/extensions/components/mail/errors.md +76 -62
- package/content/extensions/components/mail/index.md +111 -463
- package/content/extensions/components/mail/usage.md +139 -173
- package/content/extensions/components/request-tracker.md +70 -173
- package/content/extensions/components/socket-io/api.md +462 -785
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +69 -372
- package/content/extensions/components/socket-io/usage.md +212 -105
- package/content/extensions/components/static-asset/api.md +461 -141
- package/content/extensions/components/static-asset/errors.md +121 -53
- package/content/extensions/components/static-asset/index.md +84 -606
- package/content/extensions/components/static-asset/usage.md +184 -299
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +311 -404
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +75 -407
- package/content/extensions/components/websocket/usage.md +120 -338
- package/content/extensions/helpers/cron/index.md +52 -160
- package/content/extensions/helpers/crypto/index.md +67 -480
- package/content/extensions/helpers/crypto/reference.md +528 -0
- package/content/extensions/helpers/env/index.md +64 -178
- package/content/extensions/helpers/error/index.md +286 -196
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +76 -550
- package/content/extensions/helpers/inversion/reference.md +530 -0
- package/content/extensions/helpers/kafka/admin.md +23 -3
- package/content/extensions/helpers/kafka/compile-binary.md +83 -52
- package/content/extensions/helpers/kafka/consumer.md +65 -28
- package/content/extensions/helpers/kafka/examples.md +46 -253
- package/content/extensions/helpers/kafka/index.md +55 -617
- package/content/extensions/helpers/kafka/producer.md +156 -22
- package/content/extensions/helpers/kafka/schema-registry.md +59 -79
- package/content/extensions/helpers/logger/hf-logger.md +220 -0
- package/content/extensions/helpers/logger/index.md +78 -552
- package/content/extensions/helpers/logger/pino.md +105 -0
- package/content/extensions/helpers/logger/reference.md +937 -0
- package/content/extensions/helpers/network/api.md +276 -195
- package/content/extensions/helpers/network/index.md +87 -524
- package/content/extensions/helpers/queue/index.md +80 -897
- package/content/extensions/helpers/queue/reference.md +494 -0
- package/content/extensions/helpers/redis/index.md +86 -640
- package/content/extensions/helpers/redis/reference.md +784 -0
- package/content/extensions/helpers/secrets/index.md +136 -0
- package/content/extensions/helpers/socket-io/api.md +325 -204
- package/content/extensions/helpers/socket-io/index.md +79 -429
- package/content/extensions/helpers/storage/api.md +584 -464
- package/content/extensions/helpers/storage/index.md +80 -573
- package/content/extensions/helpers/types/index.md +75 -495
- package/content/extensions/helpers/types/reference.md +689 -0
- package/content/extensions/helpers/uid/index.md +176 -189
- package/content/extensions/helpers/websocket/api.md +366 -214
- package/content/extensions/helpers/websocket/index.md +68 -503
- package/content/extensions/helpers/worker-thread/index.md +62 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +5 -4
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +8 -7
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +64 -22
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +600 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +25 -46
- package/content/references/base/filter-system/application-usage.md +95 -123
- package/content/references/base/filter-system/array-operators.md +33 -43
- package/content/references/base/filter-system/comparison-operators.md +55 -63
- package/content/references/base/filter-system/default-filter.md +144 -350
- package/content/references/base/filter-system/fields-order-pagination.md +116 -148
- package/content/references/base/filter-system/index.md +114 -253
- package/content/references/base/filter-system/json-filtering.md +52 -181
- package/content/references/base/filter-system/list-operators.md +28 -44
- package/content/references/base/filter-system/logical-operators.md +69 -114
- package/content/references/base/filter-system/null-operators.md +41 -98
- package/content/references/base/filter-system/pattern-matching.md +48 -51
- package/content/references/base/filter-system/quick-reference.md +93 -196
- package/content/references/base/filter-system/range-operators.md +22 -38
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +173 -232
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +43 -28
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +81 -1452
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +281 -419
- package/content/references/base/repositories/index.md +84 -644
- package/content/references/base/repositories/mixins.md +25 -21
- package/content/references/base/repositories/relations.md +194 -375
- package/content/references/base/repositories/soft-deletable.md +67 -55
- package/content/references/base/secrets.md +267 -0
- package/content/references/base/services.md +8 -6
- package/content/references/configuration/environment-variables.md +73 -21
- package/content/references/configuration/index.md +51 -31
- package/content/references/index.md +1 -1
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +6 -2
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +81 -61
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +58 -218
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +24 -23
|
@@ -2,274 +2,171 @@
|
|
|
2
2
|
title: Filter Operators Quick Reference
|
|
3
3
|
description: Single-page cheat sheet of all filter operators
|
|
4
4
|
difficulty: intermediate
|
|
5
|
-
lastUpdated: 2026-
|
|
5
|
+
lastUpdated: 2026-07-23
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Filter Operators Quick Reference
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Every `where` operator, one line each. For the `filter` shape and the mental model, start at the [Filter System Overview](./). For explanations and worked examples, follow the **See** link under each table.
|
|
11
11
|
|
|
12
12
|
## Comparison Operators
|
|
13
13
|
|
|
14
|
-
| Operator | SQL |
|
|
15
|
-
|
|
14
|
+
| Operator | SQL | Example | Description |
|
|
15
|
+
|---|---|---|---|
|
|
16
16
|
| `eq` | `=` | `{ status: { eq: 'active' } }` | Equal to |
|
|
17
17
|
| `ne` | `!=` | `{ status: { ne: 'deleted' } }` | Not equal to |
|
|
18
|
-
| `neq` | `!=` | `{ status: { neq: 'deleted' } }` |
|
|
18
|
+
| `neq` | `!=` | `{ status: { neq: 'deleted' } }` | Alias for `ne` |
|
|
19
19
|
| `gt` | `>` | `{ age: { gt: 18 } }` | Greater than |
|
|
20
20
|
| `gte` | `>=` | `{ age: { gte: 18 } }` | Greater than or equal |
|
|
21
21
|
| `lt` | `<` | `{ price: { lt: 100 } }` | Less than |
|
|
22
22
|
| `lte` | `<=` | `{ price: { lte: 100 } }` | Less than or equal |
|
|
23
23
|
|
|
24
24
|
> [!NOTE]
|
|
25
|
-
> `ne`/`neq` follow SQL three-valued logic
|
|
25
|
+
> `ne`/`neq` follow SQL three-valued logic. A row whose field is `NULL` never matches `{ field: { neq: value } }`, because `NULL <> value` is UNKNOWN, not TRUE. To include NULL rows too, use `{ or: [{ field: { neq: value } }, { field: null }] }`.
|
|
26
26
|
|
|
27
27
|
**See:** [Comparison Operators Guide](./comparison-operators.md)
|
|
28
28
|
|
|
29
|
+
## Null / Presence Operators
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
31
|
+
| Operator | SQL | Example | Description |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| `is` | `IS NULL` / `=` | `{ deletedAt: { is: null } }` | `IS NULL` when the value is `null`, equality otherwise |
|
|
34
|
+
| `isn` | `IS NOT NULL` / `!=` | `{ email: { isn: null } }` | `IS NOT NULL` when the value is `null`, not-equal otherwise |
|
|
35
|
+
| `exists` | `IS NOT NULL` / `IS NULL` | `{ deletedAt: { exists: false } }` | `exists: true` -> `IS NOT NULL`, `exists: false` -> `IS NULL` |
|
|
36
|
+
| `notExists` | `IS NULL` / `IS NOT NULL` | `{ verifiedAt: { notExists: true } }` | Inverse of `exists` |
|
|
36
37
|
|
|
37
|
-
**
|
|
38
|
+
**Shorthand:** a bare `null` is implicit `IS NULL`. `{ deletedAt: null }` is identical to `{ deletedAt: { eq: null } }` or `{ deletedAt: { is: null } }`.
|
|
38
39
|
|
|
40
|
+
**See:** [Null Operators Guide](./null-operators.md)
|
|
39
41
|
|
|
40
42
|
## List Operators
|
|
41
43
|
|
|
42
|
-
| Operator | SQL |
|
|
43
|
-
|
|
44
|
-
| `in` | `IN` | `{ status: { in: ['active', 'pending'] } }` | Value matches any in array |
|
|
44
|
+
| Operator | SQL | Example | Description |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| `in` | `IN` | `{ status: { in: ['active', 'pending'] } }` | Value matches any in the array |
|
|
45
47
|
| `inq` | `IN` | `{ status: { inq: ['active', 'pending'] } }` | Alias for `in` |
|
|
46
|
-
| `nin` | `NOT IN` | `{ status: { nin: ['deleted', 'banned'] } }` | Value
|
|
48
|
+
| `nin` | `NOT IN` | `{ status: { nin: ['deleted', 'banned'] } }` | Value matches none in the array |
|
|
49
|
+
|
|
50
|
+
> [!NOTE]
|
|
51
|
+
> An empty array is a hard edge. `{ in: [] }` / `{ inq: [] }` match no rows; `{ nin: [] }` matches every row, because an empty exclusion list excludes nothing.
|
|
47
52
|
|
|
48
53
|
**See:** [List Operators Guide](./list-operators.md)
|
|
49
54
|
|
|
55
|
+
## Range Operators
|
|
56
|
+
|
|
57
|
+
| Operator | SQL | Example | Description |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| `between` | `BETWEEN` | `{ age: { between: [18, 65] } }` | Value is within range, inclusive |
|
|
60
|
+
| `notBetween` | `NOT BETWEEN` | `{ age: { notBetween: [0, 18] } }` | Value is outside range |
|
|
61
|
+
|
|
62
|
+
Both require a 2-element array `[min, max]` - anything else throws.
|
|
63
|
+
|
|
64
|
+
**See:** [Range Operators Guide](./range-operators.md)
|
|
50
65
|
|
|
51
66
|
## Pattern Matching Operators
|
|
52
67
|
|
|
53
|
-
| Operator | SQL |
|
|
54
|
-
|
|
55
|
-
| `like` | `LIKE` | `{ name: { like: '%john%' } }` | Pattern match
|
|
56
|
-
| `nlike` | `NOT LIKE` | `{ name: { nlike: '%test%' } }` | Inverse
|
|
57
|
-
| `ilike` | `ILIKE` | `{ email: { ilike: '%@gmail.com' } }` | Pattern match
|
|
58
|
-
| `nilike` | `NOT ILIKE` | `{ email: { nilike: '%spam%' } }` | Inverse
|
|
68
|
+
| Operator | SQL | Example | Description |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `like` | `LIKE` | `{ name: { like: '%john%' } }` | Pattern match, case-sensitive |
|
|
71
|
+
| `nlike` | `NOT LIKE` | `{ name: { nlike: '%test%' } }` | Inverse, case-sensitive |
|
|
72
|
+
| `ilike` | `ILIKE` | `{ email: { ilike: '%@gmail.com' } }` | Pattern match, case-insensitive |
|
|
73
|
+
| `nilike` | `NOT ILIKE` | `{ email: { nilike: '%spam%' } }` | Inverse, case-insensitive |
|
|
59
74
|
| `regexp` | `~` | `{ code: { regexp: '^[A-Z]{3}$' } }` | Regular expression (PostgreSQL) |
|
|
60
75
|
| `iregexp` | `~*` | `{ code: { iregexp: '^[a-z]{3}$' } }` | Case-insensitive regex (PostgreSQL) |
|
|
61
76
|
|
|
62
|
-
**
|
|
63
|
-
- `%` - Matches any sequence of characters
|
|
64
|
-
- `_` - Matches any single character
|
|
77
|
+
**Wildcards:** `%` matches any sequence of characters, `_` matches any single character.
|
|
65
78
|
|
|
66
79
|
**See:** [Pattern Matching Guide](./pattern-matching.md)
|
|
67
80
|
|
|
68
|
-
|
|
69
|
-
## Null Check Operators
|
|
70
|
-
|
|
71
|
-
| Operator | SQL | TypeScript Example | Description |
|
|
72
|
-
|----------|-----|-------------------|-------------|
|
|
73
|
-
| `is` | `IS NULL` / `=` | `{ deletedAt: { is: null } }` | IS NULL when value is `null`, equality otherwise |
|
|
74
|
-
| `isn` | `IS NOT NULL` / `!=` | `{ email: { isn: null } }` | IS NOT NULL when value is `null`, not-equal otherwise |
|
|
75
|
-
|
|
76
|
-
**Shorthand Syntax:**
|
|
77
|
-
```typescript
|
|
78
|
-
// Direct null assignment (implicit IS NULL)
|
|
79
|
-
{ deletedAt: null }
|
|
80
|
-
// SQL: WHERE "deleted_at" IS NULL
|
|
81
|
-
|
|
82
|
-
// Using eq with null
|
|
83
|
-
{ deletedAt: { eq: null } }
|
|
84
|
-
// SQL: WHERE "deleted_at" IS NULL
|
|
85
|
-
|
|
86
|
-
// Using ne with null
|
|
87
|
-
{ deletedAt: { ne: null } }
|
|
88
|
-
// SQL: WHERE "deleted_at" IS NOT NULL
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**See:** [Null Operators Guide](./null-operators.md)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
## Presence & Negation Operators
|
|
95
|
-
|
|
96
|
-
| Operator | SQL | TypeScript Example | Description |
|
|
97
|
-
|----------|-----|-------------------|-------------|
|
|
98
|
-
| `exists` | `IS NOT NULL` / `IS NULL` | `{ deletedAt: { exists: false } }` | `exists: true` -> IS NOT NULL, `exists: false` -> IS NULL |
|
|
99
|
-
| `notExists` | `IS NULL` / `IS NOT NULL` | `{ verifiedAt: { notExists: true } }` | Inverse of `exists` (`notExists: true` -> IS NULL) |
|
|
100
|
-
| `not` | `NOT (...)` | `{ status: { not: 'archived' } }` / `{ views: { not: { gt: 100 } } }` | Negates the nested condition; a bare value negates `eq` |
|
|
101
|
-
|
|
102
|
-
`exists`/`notExists`/`not` are supported on the PostgreSQL connector. `not` recurses: `{ not: { gt: 100 } }` becomes `NOT (col > 100)`, and `{ not: 5 }` becomes `NOT (col = 5)`. `exists` also works over JSON paths on PostgreSQL (`{ 'metadata.score': { exists: true } }`).
|
|
103
|
-
|
|
104
|
-
**See:** [Null Operators Guide](./null-operators.md)
|
|
105
|
-
|
|
106
|
-
|
|
107
81
|
## Logical Operators
|
|
108
82
|
|
|
109
|
-
| Operator | SQL |
|
|
110
|
-
|
|
111
|
-
| `and` | `AND` | `{ and: [{ age: { gt: 18 } }, { status: 'active' }] }` |
|
|
83
|
+
| Operator | SQL | Example | Description |
|
|
84
|
+
|---|---|---|---|
|
|
85
|
+
| `and` | `AND` | `{ and: [{ age: { gt: 18 } }, { status: 'active' }] }` | Every condition must be true |
|
|
112
86
|
| `or` | `OR` | `{ or: [{ role: 'admin' }, { role: 'moderator' }] }` | At least one condition must be true |
|
|
113
|
-
| `
|
|
87
|
+
| `not` | `NOT (...)` | `{ status: { not: 'archived' } }` / `{ views: { not: { gt: 100 } } }` | Negates the nested condition; a bare value negates `eq` |
|
|
88
|
+
| (implicit) | `AND` | `{ status: 'active', age: { gte: 18 } }` | Multiple top-level `where` keys are ANDed together |
|
|
89
|
+
| `and: []` | (dropped) | `{ and: [] }` | Vacuously true - no condition added |
|
|
114
90
|
| `or: []` | `false` | `{ or: [] }` | Vacuously false - matches no rows |
|
|
115
91
|
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
// Multiple fields = implicit AND
|
|
119
|
-
{
|
|
120
|
-
status: 'active',
|
|
121
|
-
age: { gte: 18 },
|
|
122
|
-
role: 'user'
|
|
123
|
-
}
|
|
124
|
-
// WHERE status = 'active' AND age >= 18 AND role = 'user'
|
|
125
|
-
```
|
|
92
|
+
`not` recurses: `{ not: { gt: 100 } }` becomes `NOT (col > 100)`; `{ not: 5 }` becomes `NOT (col = 5)`; `{ not: null }` becomes `IS NOT NULL`.
|
|
126
93
|
|
|
127
|
-
|
|
94
|
+
`exists`/`notExists` also work over JSON paths (`{ 'metadata.score': { exists: true } }`).
|
|
128
95
|
|
|
129
96
|
**See:** [Logical Operators Guide](./logical-operators.md)
|
|
130
97
|
|
|
98
|
+
## Array Operators (PostgreSQL)
|
|
131
99
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
These operators work with PostgreSQL array columns (`varchar[]`, `text[]`, `integer[]`, etc.).
|
|
100
|
+
For array columns (`varchar[]`, `text[]`, `integer[]`, and so on) - not to be confused with `in`/`nin`, which match a scalar against a list.
|
|
135
101
|
|
|
136
|
-
| Operator |
|
|
137
|
-
|
|
138
|
-
| `contains` | `@>` | `{ tags: { contains: ['typescript', 'nodejs'] } }` |
|
|
139
|
-
| `containedBy` | `<@` | `{ tags: { containedBy: ['ts', 'js', 'go', 'rust'] } }` |
|
|
140
|
-
| `overlaps` | `&&` | `{ tags: { overlaps: ['react', 'vue', 'angular'] } }` | Arrays
|
|
102
|
+
| Operator | SQL | Example | Description |
|
|
103
|
+
|---|---|---|---|
|
|
104
|
+
| `contains` | `@>` | `{ tags: { contains: ['typescript', 'nodejs'] } }` | Column array contains ALL given elements |
|
|
105
|
+
| `containedBy` | `<@` | `{ tags: { containedBy: ['ts', 'js', 'go', 'rust'] } }` | Column array is a subset of the given array |
|
|
106
|
+
| `overlaps` | `&&` | `{ tags: { overlaps: ['react', 'vue', 'angular'] } }` | Arrays share at least one element |
|
|
141
107
|
|
|
142
|
-
|
|
108
|
+
A scalar operand is wrapped into a single-element array automatically.
|
|
143
109
|
|
|
144
110
|
**See:** [Array Operators Guide](./array-operators.md)
|
|
145
111
|
|
|
112
|
+
## JSON Path Operators (PostgreSQL)
|
|
146
113
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
Query nested fields within JSON/JSONB columns using dot notation as the key.
|
|
150
|
-
|
|
151
|
-
### JSON Path Syntax
|
|
114
|
+
A dot-notation key targets a JSON/JSONB column instead of a top-level one.
|
|
152
115
|
|
|
153
116
|
| Syntax | Example | Description |
|
|
154
|
-
|
|
155
|
-
| Dot notation | `{ 'metadata.user.name': 'John' }` | Access nested
|
|
156
|
-
| Array index | `{ 'metadata.tags[0]': 'urgent' }` | Access array
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| Dot notation | `{ 'metadata.user.name': 'John' }` | Access a nested property |
|
|
119
|
+
| Array index | `{ 'metadata.tags[0]': 'urgent' }` | Access an array element |
|
|
157
120
|
| Combined | `{ 'metadata.users[0].email': value }` | Nested arrays and objects |
|
|
158
121
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
// Equality (string comparison via #>>)
|
|
163
|
-
{ 'metadata.user.role': 'admin' }
|
|
164
|
-
// SQL: "metadata" #>> '{user,role}' = 'admin'
|
|
165
|
-
|
|
166
|
-
// Numeric comparison (safe casting via CASE/numeric)
|
|
167
|
-
{ 'metadata.score': { gt: 80 } }
|
|
168
|
-
|
|
169
|
-
// Pattern matching
|
|
170
|
-
{ 'metadata.level': { ilike: '%high%' } }
|
|
171
|
-
// SQL: "metadata" #>> '{level}' ILIKE '%high%'
|
|
172
|
-
|
|
173
|
-
// Multiple JSON conditions
|
|
174
|
-
{
|
|
175
|
-
and: [
|
|
176
|
-
{ 'metadata.user.age': { gt: 18 } },
|
|
177
|
-
{ 'metadata.user.country': 'US' }
|
|
178
|
-
]
|
|
179
|
-
}
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Supported Operators with JSON Paths
|
|
122
|
+
**Supported operators:** `eq`, `ne`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `inq`, `nin`, `like`, `nlike`, `ilike`, `nilike`, `between`, `notBetween`, `regexp`, `iregexp`, `is`, `isn`, `exists`, `notExists`, `not`. That's the same set as top-level columns, minus the array operators (`contains`/`containedBy`/`overlaps`), which need a real array column.
|
|
183
123
|
|
|
184
|
-
|
|
185
|
-
- `eq`, `ne`, `neq`, `gt`, `gte`, `lt`, `lte`
|
|
186
|
-
- `in`, `inq`, `nin`
|
|
187
|
-
- `like`, `nlike`, `ilike`, `nilike`
|
|
188
|
-
- `between`, `notBetween`
|
|
189
|
-
- `regexp`, `iregexp`
|
|
190
|
-
- `is`, `isn`
|
|
191
|
-
- `exists`, `notExists`, `not`
|
|
192
|
-
|
|
193
|
-
Numeric operators (`gt`, `gte`, `lt`, `lte`, `between`, `notBetween`) use safe numeric casting to handle mixed JSON value types.
|
|
124
|
+
Numeric operators cast the extracted text to `numeric` automatically: `gt`, `gte`, `lt`, `lte`, `between`, `notBetween`, and `eq`/`ne`/`neq`/`in`/`inq`/`nin` when the operand is a number. So `{ 'metadata.score': { gt: 80 } }` compares as a number, not a string.
|
|
194
125
|
|
|
195
126
|
**See:** [JSON Filtering Guide](./json-filtering.md)
|
|
196
127
|
|
|
128
|
+
## Fields, Order & Pagination
|
|
197
129
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Ordering
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
// Single field
|
|
215
|
-
{ order: ['createdAt DESC'] }
|
|
216
|
-
|
|
217
|
-
// Multiple fields
|
|
218
|
-
{ order: ['status ASC', 'createdAt DESC'] }
|
|
219
|
-
|
|
220
|
-
// Default direction is ASC
|
|
221
|
-
{ order: ['name'] } // Same as 'name ASC'
|
|
222
|
-
|
|
223
|
-
// JSON path ordering
|
|
224
|
-
{ order: ['metadata.priority DESC'] }
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Pagination
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
{
|
|
231
|
-
limit: 10, // Max records to return (default: 10)
|
|
232
|
-
skip: 20, // Skip first 20 records (alias: offset)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Page 3 with 10 items per page
|
|
236
|
-
{
|
|
237
|
-
limit: 10,
|
|
238
|
-
skip: 20, // (page - 1) * limit = (3 - 1) * 10
|
|
239
|
-
}
|
|
240
|
-
```
|
|
130
|
+
| Property | Syntax | Example | Result |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `fields` (array) | `string[]` | `fields: ['id', 'name', 'email']` | `SELECT` only those columns |
|
|
133
|
+
| `fields` (object) | `{ field: true }` | `fields: { id: true, name: true }` | Same - inclusion-only, `false` is ignored |
|
|
134
|
+
| `order` | `'field ASC'` / `'field DESC'` | `order: ['createdAt DESC']` | `ORDER BY`; default direction is `ASC` (`order: ['name']` = `'name ASC'`) |
|
|
135
|
+
| `order` (JSON path) | `'a.b DESC'` | `order: ['metadata.priority DESC']` | `ORDER BY` on a JSON path |
|
|
136
|
+
| `limit` | number | `limit: 10` | `LIMIT`; omitted -> `query.limit ?? settings.defaultLimit ?? 10` |
|
|
137
|
+
| `skip` | number | `skip: 20` | `OFFSET`; alias of `offset` - `skip` wins if both are given |
|
|
138
|
+
| `offset` | number | `offset: 20` | `OFFSET`; alias of `skip` |
|
|
241
139
|
|
|
242
140
|
**See:** [Fields, Ordering & Pagination Guide](./fields-order-pagination.md)
|
|
243
141
|
|
|
142
|
+
## Default Filter
|
|
244
143
|
|
|
245
|
-
|
|
144
|
+
A model's `settings.defaultFilter` merges into every read, update, and delete for that model.
|
|
246
145
|
|
|
247
|
-
|
|
146
|
+
| Collision shape | Result |
|
|
147
|
+
|---|---|
|
|
148
|
+
| Different keys | AND-composed - `{ isDeleted: false }` default + `{ status: 'published' }` caller filter -> `WHERE "isDeleted" = false AND "status" = 'published'` |
|
|
149
|
+
| Same key, scalar vs. scalar | Caller wins - the one override escape, no `shouldSkipDefaultFilter` needed |
|
|
150
|
+
| Same key, scalar vs. operator object (either side) | AND-composed |
|
|
151
|
+
| Same key, both `and` | Concatenated - both groups hold |
|
|
152
|
+
| Same key, both `or` | Kept as two separate conjuncts, never unioned |
|
|
248
153
|
|
|
249
154
|
```typescript
|
|
250
|
-
|
|
251
|
-
type: 'entity',
|
|
252
|
-
settings: {
|
|
253
|
-
defaultFilter: {
|
|
254
|
-
where: { isDeleted: false },
|
|
255
|
-
limit: 100,
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
})
|
|
259
|
-
export class User extends BaseEntity<typeof User.schema> {
|
|
260
|
-
static override schema = userTable;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// All queries automatically include the default filter
|
|
264
|
-
await userRepository.find({ filter: {} });
|
|
265
|
-
// WHERE isDeleted = false LIMIT 100
|
|
266
|
-
|
|
267
|
-
// Skip default filter for admin operations
|
|
155
|
+
// Skip the default filter entirely
|
|
268
156
|
await userRepository.find({
|
|
269
|
-
filter: {},
|
|
157
|
+
filter: { where: { status: 'published' } },
|
|
270
158
|
options: { shouldSkipDefaultFilter: true },
|
|
271
159
|
});
|
|
272
|
-
// No automatic filter applied
|
|
273
160
|
```
|
|
274
161
|
|
|
275
162
|
**See:** [Default Filter Guide](./default-filter.md)
|
|
163
|
+
|
|
164
|
+
## See also
|
|
165
|
+
|
|
166
|
+
- [Filter System Overview](./) - the `filter` shape, `where` families at a glance, and links to every depth page
|
|
167
|
+
|
|
168
|
+
**Files:**
|
|
169
|
+
|
|
170
|
+
- [`packages/core-server/src/connectors/relational/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/connectors/relational/repositories/dialect/filter.ts) - `FilterBuilder`, translates `TFilter` to Drizzle/SQL
|
|
171
|
+
- [`packages/core-server/src/connectors/postgres/repositories/dialect/query.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/connectors/postgres/repositories/dialect/query.ts) - `PostgresQueryOperators.FNS`, one handler per operator
|
|
172
|
+
- [`packages/filter/src/common/operators.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/filter/src/common/operators.ts) - `QueryOperators`/`Sorts` constants
|
|
@@ -6,64 +6,48 @@ difficulty: intermediate
|
|
|
6
6
|
|
|
7
7
|
# Range Operators
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Matches a field against a `[min, max]` range.
|
|
10
10
|
|
|
11
|
+
| Operator | SQL | Meaning |
|
|
12
|
+
|----------|-----|---------|
|
|
13
|
+
| `between` | `BETWEEN ... AND ...` | Value is within the range (inclusive) |
|
|
14
|
+
| `notBetween` | `NOT (... BETWEEN ... AND ...)` | Value is outside the range |
|
|
11
15
|
|
|
12
16
|
## between
|
|
13
17
|
|
|
14
|
-
Find values within a range (inclusive):
|
|
15
|
-
|
|
16
18
|
```typescript
|
|
17
|
-
// Numeric range
|
|
18
19
|
{ where: { price: { between: [100, 500] } } }
|
|
19
20
|
// SQL: WHERE "price" BETWEEN 100 AND 500
|
|
20
|
-
|
|
21
|
-
// Date range
|
|
22
|
-
{
|
|
23
|
-
where: {
|
|
24
|
-
createdAt: {
|
|
25
|
-
between: [new Date('2024-01-01'), new Date('2024-12-31')]
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// SQL: WHERE "created_at" BETWEEN '2024-01-01' AND '2024-12-31'
|
|
30
|
-
|
|
31
|
-
// String range (lexicographic)
|
|
32
|
-
{ where: { lastName: { between: ['A', 'M'] } } }
|
|
33
|
-
// SQL: WHERE "last_name" BETWEEN 'A' AND 'M'
|
|
34
21
|
```
|
|
35
22
|
|
|
36
|
-
|
|
37
|
-
> The value MUST be an array with exactly 2 elements `[min, max]`. Invalid values throw an error:
|
|
38
|
-
> ```
|
|
39
|
-
> Error: [BETWEEN] Invalid value: expected array of 2 elements, got ...
|
|
40
|
-
> ```
|
|
23
|
+
**Notice:** both bounds are inclusive.
|
|
41
24
|
|
|
25
|
+
**Edge cases:**
|
|
26
|
+
- The value must be a 2-element array `[min, max]`; anything else throws `[PostgresQueryOperators][BETWEEN] Invalid value: expected array of 2 elements, got ...`.
|
|
27
|
+
- If either bound is `null`, the condition matches no rows (SQL `NULL` comparison).
|
|
28
|
+
- If `min > max`, the condition matches no rows.
|
|
42
29
|
|
|
43
30
|
## notBetween
|
|
44
31
|
|
|
45
|
-
Find values outside a range:
|
|
46
|
-
|
|
47
32
|
```typescript
|
|
48
33
|
{ where: { score: { notBetween: [40, 60] } } }
|
|
49
34
|
// SQL: WHERE NOT ("score" BETWEEN 40 AND 60)
|
|
50
|
-
// Matches: scores < 40 OR scores > 60
|
|
51
35
|
```
|
|
52
36
|
|
|
53
|
-
|
|
54
|
-
> Same validation as `between` -- the value MUST be an array with exactly 2 elements.
|
|
37
|
+
**Notice:** matches values strictly outside the range.
|
|
55
38
|
|
|
39
|
+
**Edge cases:**
|
|
40
|
+
- Same 2-element array validation as `between`, throwing `[PostgresQueryOperators][NOT_BETWEEN] Invalid value: expected array of 2 elements, got ...`.
|
|
41
|
+
- A `NULL` column matches neither `between` nor `notBetween`.
|
|
56
42
|
|
|
57
|
-
##
|
|
43
|
+
## See also
|
|
58
44
|
|
|
59
|
-
|
|
45
|
+
- [Filter System Overview](./) - the `filter` shape and the full `where` operator table
|
|
46
|
+
- [Comparison Operators](./comparison-operators) - `gt`/`gte`/`lt`/`lte`, which can express the same range as an alternative to `between`/`notBetween`
|
|
47
|
+
- [Quick Reference](./quick-reference) - every operator, one line each
|
|
60
48
|
|
|
61
|
-
|
|
62
|
-
// Equivalent to between: [100, 500]
|
|
63
|
-
{ where: { price: { gte: 100, lte: 500 } } }
|
|
64
|
-
// SQL: WHERE "price" >= 100 AND "price" <= 500
|
|
49
|
+
**Files:**
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```
|
|
51
|
+
- [`packages/core-server/src/connectors/postgres/repositories/dialect/query.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/connectors/postgres/repositories/dialect/query.ts) - `PostgresQueryOperators.FNS`, per-operator SQL builders
|
|
52
|
+
- [`packages/core-server/src/connectors/relational/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/connectors/relational/repositories/dialect/filter.ts) - `FilterBuilder`, translates `TFilter` to Drizzle/SQL
|
|
53
|
+
- [`packages/filter/src/common/operators.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/filter/src/common/operators.ts) - `QueryOperators` constants
|