MongoDB query filtering in JavaScript
npx @tessl/cli install tessl/npm-sift@17.1.0Sift 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.
npm install sift or yarn add siftimport sift from "sift";For individual operators and utilities:
import {
createQueryTester,
createOperationTester,
createQueryOperation,
createDefaultQueryOperation,
createEqualsOperation,
$eq, $gt, $in, $Size
} from "sift";CommonJS:
const sift = require("sift");
const {
createQueryTester,
createOperationTester,
createQueryOperation,
createDefaultQueryOperation,
createEqualsOperation,
$eq, $gt, $in, $Size
} = require("sift");import sift from "sift";
// Basic filtering with comparison operators
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const filtered = numbers.filter(sift({ $gt: 5 })); // [6, 7, 8, 9, 10]
// Array filtering with complex queries
const users = [
{ name: "Alice", age: 25, active: true },
{ name: "Bob", age: 30, active: false },
{ name: "Charlie", age: 35, active: true }
];
const activeAdults = users.filter(sift({
age: { $gte: 25 },
active: true
})); // [{ name: "Alice", age: 25, active: true }, { name: "Charlie", age: 35, active: true }]
// Using logical operators
const complexFilter = users.filter(sift({
$or: [
{ age: { $lt: 30 } },
{ name: "Charlie" }
]
})); // [{ name: "Alice", age: 25, active: true }, { name: "Charlie", age: 35, active: true }]
// Testing single values
const testFilter = sift({ age: { $gte: 30 } });
console.log(testFilter({ age: 35 })); // true
console.log(testFilter({ age: 25 })); // falseSift is built around several key components:
The main sift function creates filter functions with all built-in MongoDB query operations.
/**
* Creates a filter function with all built-in MongoDB query operations
* @param query - MongoDB-style query object
* @param options - Optional configuration for operations and comparison
* @returns Function that can be used with Array.filter() or for testing single values
*/
function sift<TItem, TSchema extends TItem = TItem>(
query: Query<TSchema>,
options?: Partial<Options>
): (item: TItem) => boolean;
type Query<TItemSchema> =
| TItemSchema
| RegExp
| NestedQuery<TItemSchema>;
interface Options {
operations: { [identifier: string]: OperationCreator<any> };
compare: (a: any, b: any) => boolean;
}Advanced functionality for creating custom operations and fine-grained control over query behavior.
/**
* Creates a query tester without built-in operations for custom operation sets
* @param query - Query object
* @param options - Configuration including custom operations
* @returns Filter function
*/
function createQueryTester<TItem, TSchema = TItem>(
query: Query<TSchema>,
options?: Partial<Options>
): (item: TItem) => boolean;
/**
* Creates an equals operation for custom operation development
* @param params - Parameters for the operation
* @param ownerQuery - Parent query object
* @param options - Operation options
* @returns EqualsOperation instance
*/
function createEqualsOperation(
params: any,
ownerQuery: any,
options: Options
): EqualsOperation;type Query<TItemSchema> =
| TItemSchema
| RegExp
| NestedQuery<TItemSchema>;
type NestedQuery<TItemSchema> = ValueQuery<TItemSchema> & ShapeQuery<TItemSchema>;
type ValueQuery<TValue> =
TValue extends Array<any>
? ArrayValueQuery<Unpacked<TValue>>
: BasicValueQuery<TValue>;
type ShapeQuery<TItemSchema> = TItemSchema extends NotObject
? {}
: { [k in keyof TItemSchema]?: TItemSchema[k] | ValueQuery<TItemSchema[k]> };
type QueryOperators<TValue = any> = keyof ValueQuery<TValue>;interface BasicValueQuery<TValue> {
$eq?: TValue;
$ne?: TValue;
$lt?: TValue;
$gt?: TValue;
$lte?: TValue;
$gte?: TValue;
$in?: TValue[];
$nin?: TValue[];
$all?: TValue[];
$mod?: [number, number];
$exists?: boolean;
$regex?: string | RegExp;
$size?: number;
$where?: ((this: TValue, obj: TValue) => boolean) | string;
$options?: "i" | "g" | "m" | "u";
$type?: Function;
$not?: NestedQuery<TValue>;
$or?: NestedQuery<TValue>[];
$nor?: NestedQuery<TValue>[];
$and?: NestedQuery<TValue>[];
}
interface ArrayValueQuery<TValue> extends BasicValueQuery<TValue> {
$elemMatch?: Query<TValue>;
}interface Operation<TItem> {
readonly keep: boolean;
readonly done: boolean;
propop: boolean;
reset(): void;
next(item: TItem, key?: Key, owner?: any, root?: boolean, leaf?: boolean): void;
}
type OperationCreator<TItem> = (
params: any,
parentQuery: any,
options: Options,
name: string
) => Operation<TItem>;
type Tester = (
item: any,
key?: Key,
owner?: any,
root?: boolean,
leaf?: boolean
) => boolean;
type Key = string | number;
type Comparator = (a: any, b: any) => boolean;interface Options {
operations: { [identifier: string]: OperationCreator<any> };
compare: (a: any, b: any) => boolean;
}
class EqualsOperation<TParam> implements Operation<any> {
readonly propop = true;
readonly keep: boolean;
readonly done: boolean;
constructor(params: TParam, ownerQuery: any, options: Options);
reset(): void;
next(item: any, key: Key, parent: any): void;
}