MongoDB query filtering in JavaScript
npx @tessl/cli install tessl/npm-sift@17.1.00
# Sift
1
2
Sift is a MongoDB query filtering library for JavaScript that enables developers to use MongoDB-style query operators for filtering arrays and objects. It provides comprehensive support for comparison, logical, array, element, and evaluation operators with full TypeScript support and custom operation capabilities.
3
4
## Package Information
5
6
- **Package Name**: sift
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install sift` or `yarn add sift`
10
11
## Core Imports
12
13
```typescript
14
import sift from "sift";
15
```
16
17
For individual operators and utilities:
18
19
```typescript
20
import {
21
createQueryTester,
22
createOperationTester,
23
createQueryOperation,
24
createDefaultQueryOperation,
25
createEqualsOperation,
26
$eq, $gt, $in, $Size
27
} from "sift";
28
```
29
30
CommonJS:
31
32
```javascript
33
const sift = require("sift");
34
const {
35
createQueryTester,
36
createOperationTester,
37
createQueryOperation,
38
createDefaultQueryOperation,
39
createEqualsOperation,
40
$eq, $gt, $in, $Size
41
} = require("sift");
42
```
43
44
## Basic Usage
45
46
```typescript
47
import sift from "sift";
48
49
// Basic filtering with comparison operators
50
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
51
const filtered = numbers.filter(sift({ $gt: 5 })); // [6, 7, 8, 9, 10]
52
53
// Array filtering with complex queries
54
const users = [
55
{ name: "Alice", age: 25, active: true },
56
{ name: "Bob", age: 30, active: false },
57
{ name: "Charlie", age: 35, active: true }
58
];
59
60
const activeAdults = users.filter(sift({
61
age: { $gte: 25 },
62
active: true
63
})); // [{ name: "Alice", age: 25, active: true }, { name: "Charlie", age: 35, active: true }]
64
65
// Using logical operators
66
const complexFilter = users.filter(sift({
67
$or: [
68
{ age: { $lt: 30 } },
69
{ name: "Charlie" }
70
]
71
})); // [{ name: "Alice", age: 25, active: true }, { name: "Charlie", age: 35, active: true }]
72
73
// Testing single values
74
const testFilter = sift({ age: { $gte: 30 } });
75
console.log(testFilter({ age: 35 })); // true
76
console.log(testFilter({ age: 25 })); // false
77
```
78
79
## Architecture
80
81
Sift is built around several key components:
82
83
- **Query Operations**: MongoDB-style operators ($eq, $ne, $gt, etc.) for filtering data
84
- **Operation Infrastructure**: Base classes and interfaces for extensible operation system
85
- **Type System**: Full TypeScript support with generic type preservation
86
- **Custom Operations**: Extensible system allowing custom query operators
87
- **Utility Functions**: Helper functions for comparison, type checking, and operation creation
88
89
## Capabilities
90
91
### Core Query Function
92
93
The main sift function creates filter functions with all built-in MongoDB query operations.
94
95
```typescript { .api }
96
/**
97
* Creates a filter function with all built-in MongoDB query operations
98
* @param query - MongoDB-style query object
99
* @param options - Optional configuration for operations and comparison
100
* @returns Function that can be used with Array.filter() or for testing single values
101
*/
102
function sift<TItem, TSchema extends TItem = TItem>(
103
query: Query<TSchema>,
104
options?: Partial<Options>
105
): (item: TItem) => boolean;
106
107
type Query<TItemSchema> =
108
| TItemSchema
109
| RegExp
110
| NestedQuery<TItemSchema>;
111
112
interface Options {
113
operations: { [identifier: string]: OperationCreator<any> };
114
compare: (a: any, b: any) => boolean;
115
}
116
```
117
118
[Query Operators](./query-operators.md)
119
120
### Custom Query Operations
121
122
Advanced functionality for creating custom operations and fine-grained control over query behavior.
123
124
```typescript { .api }
125
/**
126
* Creates a query tester without built-in operations for custom operation sets
127
* @param query - Query object
128
* @param options - Configuration including custom operations
129
* @returns Filter function
130
*/
131
function createQueryTester<TItem, TSchema = TItem>(
132
query: Query<TSchema>,
133
options?: Partial<Options>
134
): (item: TItem) => boolean;
135
136
/**
137
* Creates an equals operation for custom operation development
138
* @param params - Parameters for the operation
139
* @param ownerQuery - Parent query object
140
* @param options - Operation options
141
* @returns EqualsOperation instance
142
*/
143
function createEqualsOperation(
144
params: any,
145
ownerQuery: any,
146
options: Options
147
): EqualsOperation;
148
```
149
150
[Advanced Features](./advanced-features.md)
151
152
## Types
153
154
### Core Types
155
156
```typescript { .api }
157
type Query<TItemSchema> =
158
| TItemSchema
159
| RegExp
160
| NestedQuery<TItemSchema>;
161
162
type NestedQuery<TItemSchema> = ValueQuery<TItemSchema> & ShapeQuery<TItemSchema>;
163
164
type ValueQuery<TValue> =
165
TValue extends Array<any>
166
? ArrayValueQuery<Unpacked<TValue>>
167
: BasicValueQuery<TValue>;
168
169
type ShapeQuery<TItemSchema> = TItemSchema extends NotObject
170
? {}
171
: { [k in keyof TItemSchema]?: TItemSchema[k] | ValueQuery<TItemSchema[k]> };
172
173
type QueryOperators<TValue = any> = keyof ValueQuery<TValue>;
174
```
175
176
### Query Value Types
177
178
```typescript { .api }
179
interface BasicValueQuery<TValue> {
180
$eq?: TValue;
181
$ne?: TValue;
182
$lt?: TValue;
183
$gt?: TValue;
184
$lte?: TValue;
185
$gte?: TValue;
186
$in?: TValue[];
187
$nin?: TValue[];
188
$all?: TValue[];
189
$mod?: [number, number];
190
$exists?: boolean;
191
$regex?: string | RegExp;
192
$size?: number;
193
$where?: ((this: TValue, obj: TValue) => boolean) | string;
194
$options?: "i" | "g" | "m" | "u";
195
$type?: Function;
196
$not?: NestedQuery<TValue>;
197
$or?: NestedQuery<TValue>[];
198
$nor?: NestedQuery<TValue>[];
199
$and?: NestedQuery<TValue>[];
200
}
201
202
interface ArrayValueQuery<TValue> extends BasicValueQuery<TValue> {
203
$elemMatch?: Query<TValue>;
204
}
205
```
206
207
### Operation Infrastructure Types
208
209
```typescript { .api }
210
interface Operation<TItem> {
211
readonly keep: boolean;
212
readonly done: boolean;
213
propop: boolean;
214
reset(): void;
215
next(item: TItem, key?: Key, owner?: any, root?: boolean, leaf?: boolean): void;
216
}
217
218
type OperationCreator<TItem> = (
219
params: any,
220
parentQuery: any,
221
options: Options,
222
name: string
223
) => Operation<TItem>;
224
225
type Tester = (
226
item: any,
227
key?: Key,
228
owner?: any,
229
root?: boolean,
230
leaf?: boolean
231
) => boolean;
232
233
type Key = string | number;
234
type Comparator = (a: any, b: any) => boolean;
235
```
236
237
### Utility Types
238
239
```typescript { .api }
240
interface Options {
241
operations: { [identifier: string]: OperationCreator<any> };
242
compare: (a: any, b: any) => boolean;
243
}
244
245
class EqualsOperation<TParam> implements Operation<any> {
246
readonly propop = true;
247
readonly keep: boolean;
248
readonly done: boolean;
249
250
constructor(params: TParam, ownerQuery: any, options: Options);
251
reset(): void;
252
next(item: any, key: Key, parent: any): void;
253
}
254
```