snapjson
v2.0.0
Published
A simple ORM for Node.js using JSON file
Maintainers
Readme
snapjson
snapjson is a lightweight NoSQL object-relational mapping (ORM) library for Node.js, written in TypeScript. It allows you to store data in JSON files, with each collection represented as an array of documents.
Table of Contents
- Installation
- Getting Started
- Command Line Interface (CLI)
- Advanced Usage
- Reporting Issues
- License
Installation
Using npm:
npm install snapjsonUsing yarn:
yarn add snapjsonUsing pnpm:
pnpm add snapjsonGetting Started
To use the snapjson module, follow these simple steps:
- For a quick start, we provide CLI commands to configure the database and create collections rapidly. To access the CLI commands, click here.
Importing the SnapJson class
import { SnapJson, createCollection } from "snapjson";Creating an instance of SnapJson
To use SnapJson, you need to create an instance of the class. You can configure it by passing an options object or by using environment variables.
🔹 Option 1: Using a configuration object
const config = {
path_db: "db",
};
const orm = new SnapJson(config);Available Options
| Option | Type | Default | Description | | --------- | ----------------------------------- | --------- | ------------------------------------------------------ | | path_db | string (optional) | "db" | Directory where JSON data will be stored | | splitFile | boolean (optional) | false | If true, each collection is stored in its own file | | encrypted | boolean (optional) | false | It true, data will be encrypted | | secretKey | string (optional) | undefined | Key used for encryption | | salt | string (optional) | undefined | Optional salt for additional encryption security | | mode | string (optional) ("prod" et "dev") | "dev" | Defines the working mode (development or production) |
🔹 Option 1: Using environment variables
SnapJson also supports environment variables for configuration. If environment variables are set, you can instantiate SnapJson without passing any config object.
const orm = new SnapJson();Available Options
| Variable Name | Default | Description |
| ------------------ | ------------- | ------------------------------------------------------------------------------------------- |
| SNAPJSON_PATH_DB | "db" | Directory where JSON data will be stored |
| SNAPJSON_SPLITFILE | "false" | If true, each collection is stored in its own file |
| SNAPJSON_ENCRYPTED | "false" | It true, data will be encrypted |
| SNAPJSON_SECRETKEY | " " | Key used for encryption |
| SNAPJSON_SALT | " " | Optional salt for additional encryption security |
| NODE_ENV | "environment" | Defines the working mode (development or production). values: environment et production |
Defining the data schema
Define your data schema using TypeScript interfaces (the __id property will be added automatically for the primary key):
interface UserSchema {
name: string;
email: string;
password: string;
age?: number;
}Creating a collection
// Option 1: Simple collection creation
const collection = await orm.createCollection("user"); // It returns instance of this collection.
console.log(collection); // user
// Option 2: Creating multiple collections at once
const collections = await orm.createCollections(["user", "teacher"]);
console.log(collections); // [ 'user', 'teacher' ]
// Option 3: Creating collection with unique key
const collection = await orm.createCollection({
collectionName: "user",
uniqueKeys: ["email"], // This defines all properties that will be unique.
});Collection Configuration Options
| Property | Description | | -------------- | ----------------------------------------------------------- | | collectionName | Name of the collection | | uniqueKeys | Defines all properties that will be unique. | | idStrategy | Defines how document IDs are generated. (uuid et increment) | | createdAt | Date when the document was first created | | updatedAt | Date when the document was last updated. |
Alternatively, you can use a shortcut helper function:
// Instead of orm.createCollection and orm.createCollections, you can use: createCollection function, imported from snapjson.
// createCollection<T>(collection: string | { collectionName: string; uniqueKeys?: Array<keyof T>; }, opts?: {...,force?: boolean}).
const collection = await createCollection("user");
const config = {
path_db: "id",
splitFile: true,
mode: "dev",
};
const collections = await createCollection(["user", "teacher"], config);Defining a collection
To define a collection, you have three methods available:
Method 1: Using the SnapJson Class
import { SnapJson } from "snapjson";
const config = {
path_db: "id",
splitFile: true,
mode: "dev",
};
const orm = new SnapJson(config);
const usersCollection = await orm.collection<UserSchema>("user");
const usersCollection = await orm.collection<UserSchema>("user", true); // create collection 'user' when it doesn't exist.This will return an instance of this collection if it exists, otherwise, an error will be thrown.
Method 2: Using shortcut helper function
import { defineCollection } from "snapjson";
const config = {
path_db: "id",
splitFile: true,
mode: "dev",
force: true, // If true, create collection 'user' when it doesn't exist.
};
const usersCollection = await defineCollection<UserSchema>("user", config);
const usersCollection = await defineCollection<UserSchema>("user", config);Method 3: Using the Collection Class
import { Collection } from "snapjson";
const config = {
path_db: "id",
splitFile: true,
mode: "dev",
force: true, // If true, create collection 'user' when it doesn't exist.
};
const usersCollection = new Collection<UserSchema>("user", config);The key difference between these methods is in their verification timing. The first and second method check if the collection exists before instantiation, while the third method checks upon execution of query methods such as find, findOne, and more.
Removing a collection
const collection = await orm.removeCollection("user");
console.log(collection); // user
const collections = await orm.removeCollection(["teacher", "student"]);
console.log(collections); // [ 'teacher', 'student' ]
// Or
// removeCollection(collections: string | string[], opts?: {...,force?: boolean})
await removeCollection("user");
await removeCollection(["teacher", "student"]);Query Methods
Use collection methods for querying:
Inserting documents
const usersCollection = await orm.collection<UserSchema>("user");
// Or
const usersCollection = await defineCollection<UserSchema>("user");
// Inserting one document
const alice = await usersCollection.insertOne({
email: "[email protected]",
name: "Alice",
password: "!13x47dh32",
age: 25,
});
console.log(alice.toObject());
/*
{
email: '[email protected]',
name: 'Alice',
password: '!13x47dh32',
age: 25,
__id: 1
}
*/
// Inserting multiple documents at once
const users = await usersCollection.insertMany([
{
email: "[email protected]",
name: "Carole",
password: "!13x9dnsnv",
age: 22,
},
{
email: "[email protected]",
name: "Mary",
password: "xnjsd7432&8",
age: 20,
},
]);
users.forEach((user) => {
console.log(user.toObject());
});
/*
{
email: '[email protected]',
name: 'Carole',
password: '!13x9dnsnv',
age: 22,
__id: 2
}
{
email: '[email protected]',
name: 'Mary',
password: 'xnjsd7432&8',
age: 20,
__id: 3
}
*/Finding documents
// Finding one document
const carole = await usersCollection.findOne(
{ name: "Carole" },
{ select: ["__id", "age", "email", "name"] }
);
if (carole) console.log(carole.toObject());
/*
{
email: '[email protected]',
name: 'Carole',
age: 22,
__id: 2
}
*/
// Finding documents
const users = await usersCollection.find(
{ age: { $gte: 20 } },
{ select: ["__id", "age", "email", "name"], limit: 3 }
);
users.forEach((user) => {
console.log(user.toObject());
});
/*
{ __id: 1, age: 25, email: '[email protected]', name: 'Alice' }
{ __id: 2, age: 22, email: '[email protected]', name: 'Carole' }
{ __id: 3, age: 20, email: '[email protected]', name: 'Mary' }
*/Updating documents
/*
Before updating:
{
email: '[email protected]',
name: 'Mary',
password: 'xnjsd7432&8',
age: 20,
__id: 3
}
*/
const data = { age: 21 };
const user = await usersCollection.updateOne(data, { __id: 3 });
if (user) console.log(user.toObject());
/*
After updating:
{
email: '[email protected]',
name: 'Mary',
password: 'xnjsd7432&8',
age: 21, ✔
__id: 3
}
*/Deleting documents
const user = await usersCollection.deleteOne({ __id: 3 });
if (user) console.log(user.toObject());
/*
{
email: '[email protected]',
name: 'Mary',
password: 'xnjsd7432&8',
age: 21,
__id: 3
}
*/Document methods
The Document object provides several methods for manipulating the properties of the document:
| Name | Description |
| -------- | ------------------------------------------------------------------------------------ |
| delete | Deletes the document from the collection. |
| save | Saves the changes to the document. |
| toJSON | Converts the document into JSON. |
| toObject | Converts the document into a plain object. |
| update | Updates the document. If the save flag is set to true, the document will be saved. |
const user = await usersCollection.findById(1);
if (user) {
console.log(user.toObject());
console.log(user.toJSON());
user.age = 10;
await user.save();
await user.delete();
}Additional methods
SnapJson class
/*
- getCollections
- isExistCollection
- size
- pathDB
*/
const collections = await orm.getCollections(); // Returns all collection names available in the database.
console.log(collections); // [ 'user' ]
const isExists = await orm.isExistCollection("user"); // Returns true if the collection exists in the database, otherwise returns false.
console.log(isExists); // true
const databaseSize = await orm.size(); // Returns the size of the database file.
console.log(databaseSize); // 58 KB
console.log(orm.pathDB); // db/Collection class
/*
- addUniqueKey
- getUniqueKeys
- removeUniqueKey
- removeUniqueKey
- removeAllUniqueKeys
- count
- size
- lastInsertId
- add
- create
*/
// addUniqueKey
const key = await usersCollection.addUniqueKey("email");
console.log(key); // email
const keys = await usersCollection.addUniqueKey(["email", "name"]);
console.log(key); // [ 'email', 'name' ]
// getUniqueKeys
const keys = await usersCollection.getUniqueKeys();
console.log(keys); // [ 'email', 'name' ]
// removeUniqueKey
const keys = await usersCollection.removeUniqueKey("name");
console.log(keys); // name
// removeAllUniqueKeys
const keys = await usersCollection.removeAllUniqueKeys();
console.log(keys); // [ 'email', 'name' ]
// count
const ct = await usersCollection.count();
console.log(ct); // 3
// Or
await usersCollection.count({ age: { $lte: 30 } });
// size
const collectionSize = await usersCollection.size();
console.log(collectionSize); // 26 KB
// lastInsertId
const id = await usersCollection.lastInsertId();
console.log(id); // 3
// add and create methods are aliases for insertOne methodCommand Line Interface (CLI)
SnapJson includes a powerful CLI tool built-in for managing your database configuration, creating and deleting collections, and defining relationships between collections. The CLI is automatically available when you install SnapJson.
Using the CLI
After installing SnapJson, you can use the CLI with:
npx snapjson [command] [flags]Or if you've installed SnapJson globally:
npm install -g snapjson
snapjson [command] [flags]Database Configuration
Before using any CLI commands, you need to configure your database.
Initialize Database Configuration
snapjson initThis interactive command will prompt you for:
- Database path: Where your JSON data files will be stored (default:
db) - Mode: Development or production mode
- Encryption: Enable/disable data encryption
- File splitting: Whether to split data into multiple files
- Secret key and salt (if encryption is enabled): For securing your data
To use default values without prompts:
snapjson init --yesExample:
$ snapjson init
? Enter database path (db): mydata
? Select mode (dev/prod): prod
? Enable encryption? (yes/NO): yes
? Enable file splitting? (yes/NO): no
✓ Database configuration saved to .env fileCollection Management
Create Collections
snapjson create -cor
snapjson c -cThis interactive command prompts for:
- Collection name: Name of your collection (e.g.,
users,posts) - Unique keys: Fields that must be unique (comma-separated)
- ID strategy:
incrementoruuid - createdAt field: Auto-add creation timestamp
- updatedAt field: Auto-add update timestamp
Example:
$ snapjson create -c
=== Create Collection ===
? Enter collection name: users
? Does this collection have unique keys? (yes/NO): yes
? Enter unique keys (comma-separated, e.g., "email,username"): email,username
? ID Strategy - increment or uuid (default: increment): uuid
? Add createdAt field? (yes/NO): yes
? Add updatedAt field? (yes/NO): yes
✓ Collection "users" created successfully!
? Create another collection? (yes/NO): no
✓ All collections created successfully!
Use 'snapjson list --collection' to view all collectionsList Collections
snapjson list -cor
snapjson l -cExample output:
$ snapjson list -c
=== Collections ===
1. users
2. posts
3. commentsDelete Collections
snapjson delete -cor
snapjson d -cYou'll be prompted to enter the collection names (space-separated):
Example:
$ snapjson delete -c
? Enter collections to remove ("profile user post ..."): users posts
Collections removed successfully : users, postsRelation Management
Create Relations
snapjson create -ror
snapjson c -rThis interactive command prompts for:
- Target collection: The collection being referenced
- Source collection: The collection containing the reference
- Relation type:
hasOne,hasMany, orbelongsTo - Local key: Field in the local collection
- Foreign key: Field in the related collection
- Relation field/alias: Name of the relation property
- Referential actions:
CASCADE,SET NULL,RESTRICT, orNO ACTIONfor delete/update operations
Example:
$ snapjson create -r
Available collections: users, posts, comments
=== Create Relation ===
? Enter target collection name: users
? Enter source collection name: posts
? Relation type (hasOne/hasMany/belongsTo) (default: hasOne): hasOne
? Local key (default: usersId): author_id
? Foreign key: (default: __id): id
? Enter relation field (default: posts): posts
? Enter the referential action when deleting (CASCADE/SET NULL/RESTRICT/NO ACTION) (default: SET NULL): CASCADE
? Enter the referential action when updating (CASCADE/SET NULL/RESTRICT/NO ACTION) (default: CASCADE): CASCADE
✓ Relation created: users -> posts (hasOne)
? Create another relation? (yes/NO): no
✓ All relations created successfully!
Use 'snapjson list --relation' to view all relationsList Relations
snapjson list -ror
snapjson l -rExample output:
$ snapjson list -r
=== Relations ===
1. posts belongsTo users
2. comments belongsTo posts
3. users hasMany postsDelete Relations
snapjson delete -ror
snapjson d -rYou'll be prompted for:
- Target collection: The collection referenced in the relation
- Source collections: The collections containing the references (space-separated)
Example:
$ snapjson delete -r
? Enter target collection name: users
? Enter the names of the source collections ("profile post ..."): posts comments
Relations removed successfully : posts, commentsHelp and Version
Display available commands:
snapjson --helpor
snapjson -hDisplay the installed version:
snapjson --versionor
snapjson -vComplete Workflow Example
Here's a step-by-step example of setting up a blog database:
# 1. Initialize database
snapjson init --yes
# 2. Create collections
snapjson create -c
# Create: users, posts, comments
# 3. List created collections
snapjson list -c
# 4. Define relationships
snapjson create -r
# Create: posts belongsTo users, comments belongsTo posts, users hasMany posts
# 5. View all relationships
snapjson list -r
# 6. Use in your codeThen use it in your TypeScript/JavaScript code:
import { SnapJson } from "snapjson";
const orm = new SnapJson();
// Collections are now configured and ready to use
const users = await orm.collection("users");
const posts = await orm.collection("posts");
const comments = await orm.collection("comments");
// Create a new user
await users.add({ name: "John", email: "[email protected]" });
// Create a post with relation to user
await posts.add({ title: "My Blog", author_id: 1 });Advanced Usage
Defining Relations Between Collection
Overview
SnapJson now supports joining collections, enabling developers to define relationships between JSON-based data structures, similar to joins in relational databases – but tailored for NoSQL-like flexibility.
With this feature, you can link documents across collections using a reference key, retrieve related data effortlessly, and keep your logic clean and organized. Whether you're working with embedded references or external collection links, SnapJson makes it easy to simulate relational behavior in a JSON environment.
This is especially useful for scenarios where your data is stored in separate collections but logically connected – like users and posts, categories and products, or invoices and clients.
Relations Syntax
You can define relations at collection creation using the relations property.
relations: {
collectionName: string; // Name of the related collection (e.g., "user")
localKey?: string; // Field in the current collection (default: `{parent name}Id`)
foreignKey?: string; // Field in the related collection (default: "__id")
as?: string; // Alias name for the relation (default: parent name)
relationType?: "belongsTo" | "hasOne" | "hasMany"; // Default: "hasOne"
onUpdate?: "cascade" | "set null" | "restrict" | "no action"; // Default: "cascade"
onDelete?: "cascade" | "set null" | "restrict" | "no action"; // Default: "set null"
}await orm.createCollection({
collectionName: "profile",
relations: [
{
collectionName: "user",
localKey: "userId",
foreignKey: "__id",
as: "user",
relationType: "belongsTo",
onUpdate: "cascade",
onDelete: "set null",
},
],
});
// Here, profile belongs to userSupported Relation Types
| Type | Description | | --------- | ------------------------------------------------------------- | | belongsTo | The current collection belongs to a parent collection | | hasOne | The current collection has one related child collection | | hasMany | The current collection has multiple related child collections |
Relation Options
| Option | Behavior | | -------- | ------------------------------------------------------------------------------------- | | cascade | Automatically updates or deletes the related collection | | set null | Sets the related collection to null on delete or sets the local key to null on update | | restrict | Prevents deletion or update if there's relation | | no acton | No automatic behavior |
Default:
- onUpdate: "cascade"
- onDelete: "set null"
Using Relation in Queries
Once defined, you can retrieve related data using include property.
await usersCollection.find( {}, { include : "profile" );
/*
[
{
__id: "1",
name: "Alice",
profile: {
__id: "1",
bio: "Software Engineer",
userId: "1",
},
},
];
*/This will include the related user object under the key user (or whatever alias was defined in as)
Note: the joined documents is embedded directly as object. hasMany joins will embed an array of objects instead.
hasMany Join Example
await studentsCollection.find(
{},
{
include: {
collectionName: "student",
limit: 10,
},
}
);
/*
[
{
__id: "1",
name: "Alice",
marks: [
{
__id: "1",
userId: "1",
info: 7,
maths: 8,
geo: 6,
},
{},...
],
},
];
*/Using Query Operators
Operators are special symbols or keywords that allow you to carry out mathematical or logical operations. snapjson provides a large number of operators to help you build complex queries.
snapjson offers the following query operator types:
- Comparison
- Logical
- Array
Comparison Operators
snapjson comparison operators can be used to compare values in a document. The following table contains the common comparison operators.
| Operators | Description | | --------- | --------------------------------------------------------------- | | $eq | Matches values that are equal to the given value. | | $ne | Matches values that are not equal to the given value. | | $gt | Matches if values are greater than the given value. | | $gte | Matches if values are greater than or equal to the given value. | | $lt | Matches if values are less than the given value. | | $lte | Matches if values are less than or equal to the given value. | | $in | Matches any of the values in an array. | | $nin | Matches none of the values specified in an array. |
$eq Operator
In this example, we retrieve the document with the exact id value 2.
const user = await usersCollection.findOne({ __id: { $eq: 2 } });
if (user) console.log(user.toObject());
/*
{
email: '[email protected]',
name: 'Carole',
password: '!13x9dnsnv',
age: 22,
__id: 2
}$ne Operator
Suppose we have a collection of students, and we need to find all documents whose age field is not equal to 40:
await studentsCollection.find({ age: { $ne: 40 } }))
/*
[
{
__id: 1,
name: "Gonzalez Estrada",
gender: "male",
age: 39,
email: "[email protected]",
},
{
__id: 2,
name: "Burris Leon",
gender: "male",
age: 37,
email: "[email protected]",
},
{
__id: 3,
name: "Maryanne Wagner",
gender: "female",
age: 32,
email: "[email protected]",
},
];
*/$gt Operator
In this example, we retrieve the documents where the age field is greater than 35:
await studentsCollection.find({ age: { $gt: 35 } });
/*
[
{
__id: 1,
name: "Gonzalez Estrada",
gender: "male",
age: 39,
email: "[email protected]",
},
{
__id: 2,
name: "Burris Leon",
gender: "male",
age: 37,
email: "[email protected]",
},
{
__id: 6,
name: "Alyce Strickland",
gender: "female",
age: 40,
email: "[email protected]",
},
];
*/$lt Operator
Let’s find the documents whose age field is less than 35:
await studentsCollection.find({ age: { $lt: 35 } });
/*
[
{
__id: 3,
name: "Maryanne Wagner",
gender: "female",
age: 32,
email: "[email protected]",
},
{
__id: 4,
name: "Fay Fowler",
gender: "female",
age: 24,
email: "[email protected]",
},
{
__id: 5,
name: "Angeline Conner",
gender: "female",
age: 20,
email: "[email protected]",
},
];
*/$gte Operator
Suppose we have a collection of students, and we need to find all documents whose age field is greater than or equal to 35.
await studentsCollection.find({ age: { $gte: 35 } });
/*
[
{
__id: 24,
name: "Linda Henderson",
gender: "female",
age: 35, ✔
email: "[email protected]",
},
{
__id: 26,
name: "Beryl Howe",
gender: "female",
age: 40,
email: "[email protected]",
},
{
__id: 28,
name: "Russell Mcclure",
gender: "male",
age: 39,
email: "[email protected]",
},
];
*/$lte Operator
Let’s find the documents whose age field is less than or equal to 35.
await studentsCollection.find({ age: { $lte: 35 } });
/*
[
{
__id: 29,
name: "Mcmahon Wilkinson",
gender: "male",
age: 23,
email: "[email protected]",
},
{
__id: 30,
name: "Nita Knapp",
gender: "female",
age: 35, ✔
email: "[email protected]",
},
{
__id: 31,
name: "Sampson Morrison",
gender: "male",
age: 26,
email: "[email protected]",
},
];
*/$in Operator
The following query returns documents where the age field contains the given values.
await studentsCollection.find({ age: { $in: [20, 30, 40] } });
/*
[
{
__id: 70,
name: "Hilary Watson",
gender: "female",
age: 20,
email: "[email protected]",
},
{
__id: 82,
name: "Estrada Ramsey",
gender: "male",
age: 30,
email: "[email protected]",
},
{
__id: 91,
name: "Lela Howard",
gender: "female",
age: 40,
email: "[email protected]",
},
];
*/$nin Operator
In this example, we retrieve the documents where the age field doesn't contain the given values.
await studentsCollection.find({ age: { $nin: [20, 30, 40] } });
/*
[
{
__id: 1,
name: "Gonzalez Estrada",
gender: "male",
age: 39,
email: "[email protected]",
},
{
__id: 2,
name: "Burris Leon",
gender: "male",
age: 37,
email: "[email protected]",
},
{
__id: 3,
name: "Maryanne Wagner",
gender: "female",
age: 32,
email: "[email protected]",
},
];
*/Logical Operators
Logical operators are used to filter data based on given conditions. They provide a way to combine multiple conditions.
snapjson provides two logical operators: $or and $and.
| Operator | Description | | -------- | ----------------------------------------------------------------------------------------------------- | | $and | Joins two or more queries with a logical AND and returns the documents that match all the conditions. | | $or | Join two or more queries with a logical OR and return the documents that match either query. |
$and Operator
Find documents that match both the following conditions:
◻ gender is equal to "male" ◻ age is between 20 and 25
await studentsCollection.find({
$and: [
{ gender: "male" },
{ age: { $gte: 20, $lte: 25 } },
]
})
/*
[
{
__id: 13,
name: "Martinez Potts",
gender: "male",
age: 20,
email: "[email protected]",
},
{
__id: 22,
name: "Patton Molina",
gender: "male",
age: 22,
email: "[email protected]",
},
{
__id: 27,
name: "Key Mercado",
gender: "male",
age: 25,
email: "[email protected]",
},
];
/*$or Operator
Find documents that match either of the following conditions:
◻ gender is equal to "male" or "female"
await studentsCollection.find({
$or: [{ gender: "male" }, { gender: "female" }],
});
/*
[
{
__id: 1,
name: "Gonzalez Estrada",
gender: "male",
age: 39,
email: "[email protected]",
},
{
__id: 2,
name: "Burris Leon",
gender: "male",
age: 37,
email: "[email protected]",
},
{
__id: 3,
name: "Maryanne Wagner",
gender: "female",
age: 32,
email: "[email protected]",
},
];
*/Array Operators
snapjson provides several operators for searching arrays. Here are the array operators provided by snapjson.
| Operator | Description | | ----------- | ------------------------------------------------------------------------------------------ | | $eq | Matches arrays that equal to the specified array. e.g. [1, 2, 3] == [1, 2, 3] | | $ne | Matches arrays that do not equal to the specified array. e.g. [1, 2, 3] !== [3, 2, 1] | | $contains | Matches arrays that contain all the specified values. | | $nocontains | Matches arrays that do not contain all the specified values. |
Basic query
Suppose we have a collection of shoes, and we need to find all shoes that have 3 colors: the first color is red, second is white, and third is green.
await shoesCollection.find({ colors: ["red", "white", "green"] });
/*
[
{
__id: 231,
price: '$88',
colors: [ 'red', 'white', 'green' ],
rate: 4,
nb_view: 836,
madeIn: 'Peru'
}
]
*/
// Note that arr1 and arr2 are not equal; on the other hand, arr3 and arr4 are equal.
const arr1 = [1, 2, 3];
const arr2 = [3, 2, 1];
const arr3 = [1, [2], 3];
const arr4 = [1, [2], 3];$eq and $ne operators
We have already explained in detail their use cases. They are used in the same way for the arrays.
$contains operator
Suppose we have a collection of shoes, and we need to find all shoes that have at least 2 colors: white and black.
await shoesCollection.find({ colors: { $contains: ["black", "white"] } });
/*
[
{
__id: 361,
price: "$48",
colors: ["blue", "black", "white"],
rate: 0,
nb_view: 163,
madeIn: "Spain",
},
{
__id: 411,
price: "$50",
colors: ["black", "green", "white"],
rate: 4,
nb_view: 100,
madeIn: "Korea (South)",
},
{
__id: 611,
price: "$79",
colors: ["white", "black"],
rate: 4,
nb_view: 784,
madeIn: "Comoros",
},
];
*/$nocontains operator
In this example, we retrieve the documents where the colors field doesn't contain white and black colors at once..
await shoesCollection.find({ colors: { $nocontains: ["black", "white"] } });
/*
[
{
__id: 971,
price: "$54",
colors: ["blue", "brown", "green"],
rate: 0,
nb_view: 692,
madeIn: "Indonesia",
},
{
__id: 981,
price: "$44",
colors: ["yellow", "white"], => Here, white color is alone.
rate: 4,
nb_view: 632,
madeIn: "Malawi",
},
{
__id: 991,
price: "$45",
colors: ["cyan", "purple", "red"],
rate: 4,
nb_view: 955,
madeIn: "Malta",
},
];
*/
await shoesCollection.find({ colors: { $nocontains: "white" } });
/*
[
{
__id: 971,
price: "$54",
colors: ["blue", "brown", "green"],
rate: 0,
nb_view: 692,
madeIn: "Indonesia",
},
{
__id: 991,
price: "$45",
colors: ["cyan", "purple", "red"],
rate: 4,
nb_view: 955,
madeIn: "Malta",
},
];
*/Working with Regular Expressions
snapjson supports regular expressions for string-based queries. You can use regular expressions with various operators to search for patterns within string.
await studentsCollection.find({ email: /.com$/ });
// $eq
await studentsCollection.find({ email: { $eq: /.com$/ } });
// $ne
await studentsCollection.find({ email: { $ne: /.com$/ } });
// $in
await studentsCollection.find({ email: { $in: [/.com$/, /.org$/] } });
// $nin
await studentsCollection.find({ email: { $nin: [/.com$/, /.org$/] } });
// $contains
await shoesCollection.find({ colors: { $contains: [/re/, "cyan"] } });
/*
[
{
__id: 631,
price: "$91",
colors: ["white", "green", "cyan"],
rate: 0,
nb_view: 817,
madeIn: "Armenia",
},
{
__id: 721,
price: "$11",
colors: ["red", "blue", "cyan"],
rate: 1,
nb_view: 849,
madeIn: "Moldova",
},
{
__id: 991,
price: "$45",
colors: ["cyan", "green", "red"],
rate: 4,
nb_view: 955,
madeIn: "Malta",
},
];
*/Reporting Issues
If you encounter any issues, have questions, or want to contribute to the project, please visit the GitHub repository and open an issue.
License
This project is licensed under the MIT License.
