A lightweight, in-memory document database for smaller projects.
You can think of this as MongoDB's little brother.
Installation
npm i @prsm/db
API overview
For a more thorough API reference, please look at the tests in this repository.
Creating a collection
A collection is just a .json
file.
import { Collection } from "@prism/db";
type Planet = {
planet: string;
diameter: number;
population?: number;
temp: {
avg: number;
};
};
const collection = new Collection<Planet>(".data", "planets");
Inserting
collection.insert({ planet: "Mercury", diameter: 4880, temp: { avg: 475 } });
collection.insert([
{ planet: "Venus", diameter: 12_104, temp: { avg: 737_000 } },
{ planet: "Earth", diameter: 12_742, temp: { avg: 288 } },
]);
Finding
collection.find({ avg: 288 });
collection.find({ planet: "Earth" });
collection.find({ diameter: { $gt: 12_000 } });
collection.find({ temp: { avg: { $lt: 1_000 } } });
collection.find({ $and: [{ avg: { $gt: 100 } }, { avg: { $lt: 10_000 } }] });
Updating
Any queries that work with .find
work with .update
.
collection.update({ planet: "Earth" }, { $inc: { population: 1 } });
Removing
Any queries that work with .find
work with .remove
.
collection.remove({ $not: { planet: "Earth" } });
Query options
find
, update
and remove
accept a QueryOptions
object.
{
deep: boolean;
ifNull: Record<string, any>;
ifEmpty: Record<string, any>;
ifNullOrEmpty: Record<string, any>;
sort: { [property: string]: -1 | 0 | 1 };
skip: number;
take: number;
project: {
[property: string]: 0 | 1;
};
aggregate: {
[property: string]:
Record<"$floor", string> |
Record<"$ceil", string> |
Record<"$sub", (string|number)[]> |
Record<"$mult", (string|number)[]> |
Record<"$div", (string|number)[]> |
Record<"$add", (string|number)[]>;
};
join: Array<{
collection: Collection<any>;
from: string;
on: string;
as: string;
options?: QueryOptions;
}>;
}
ifNull
collection.find({ a: 1 }, { ifNull: { d: 4 } });
ifEmpty
collection.find({ a: 1 }, { ifEmpty: { d: 4 } });
Sorting
collection.find({ age: { $gt: 1 } }, { sort: { age: 1, name: -1 } });
Skip & take (i.e. LIMIT)
Mostly useful when paired with sort
.
collection.find({ a: { $gt: 0 } }, { skip: 1, take: 1 });
Projection
The ID property of a document is always included unless explicitly excluded.
Implicit exclusion
When all projected properties have a value of 1
, this
is "implicit exclusion" mode.
In this mode, all document properties that are not defined
in the projection are excluded from the result document.
collection.find({ a: 1 }, { project: { b: 1 } });
Implicit inclusion
When all projected properties have a value of 0
, this
is "implicit inclusion" mode.
In this mode, all document properties that are not defined
in the projection are included from the result document.
collection.find({ a: 1 }, { project: { b: 0 } });
Explicit
In the only remaining case, all document properties
are included unless explicitly removed with a 0
.
This is effectively the same behavior as implicit inclusion.
collection.find({ a: 1 }, { project: { b: 1, c: 0 } });
Aggregation
collection.find(
{},
{
aggregate: {
total: { $add: ["math", "english", "science"] },
average: { $div: ["total", 3] },
},
project: {
_id: 0,
total: 0,
},
}
);
Joining
users.find(
{ name: "Alice" },
{
join: [
{
collection: tickets,
from: "purchasedTicketIds",
on: "_id",
as: "tickets",
options: {
project: { _id: 0 },
},
},
],
}
);
join
allows for QueryOptions
which in turn alows for join
.
This means that joins can be chained for more complex relationships
between collections.
users.find(
{ .. },
{
join: [{
collection: tickets,
options: {
join: [{
collection: seats,
options: {
join: [{
collection: auditoriums,
}]
}
}]
}
}]
}
);
Misc
Renaming builtin property names
The default property names for document ID (default _id
), "created at"
(default _created_at
) and "updated at" (default _updated_at
) timestamps can all be changed.
import { ID_KEY, CREATED_AT_KEY, UPDATED_AT_KEY } from "@prism/db";
ID_KEY = "id";
CREATED_AT_KEY = "createdAt";
UPDATED_AT_KEY = "updatedAt";
If you do this, make sure to do it at the beginning of collection creation.
Documents
The returned value from find
, update
and remove
is always an array, even when there
are no results.