Mongster

Getting Started

Quick Start

Build a todo list application with Mongster

To get started with Mongster, install the official MongoDB Node.js driver and the Mongster package.

npm i mongodb mongster

Let's build a todo list application with two schemas: User and Todo. This example demonstrates the core Mongster features including schema definition, type inference, relationships, querying, and CRUD operations.

Define Your Schemas

Mongster gives you a "zod-like" schema builder which is intuitive, and DX friendly.

User schema

import { ,  } from "mongster";

const  = .({
  : .().(1).(100),
  : .()
    .(/^[^\s@]+@[^\s@]+\.[^\s@]+$/) // DO NOT use this RegEx in production!!!
    .(),
}).();

export const  = ("users", );

Todo schema


const  = .({
  : .().(1).(200),
  : .().(false),
  : .().(),
  : .().(() => ), // [!code highlight]
}).();

export const  = ("todos", );

Infer types from your schema

Mongster let's you infer the document type inside database, what the input expects when creating a model and a few more helper types. All from a single schema!

type  = M.<typeof >;
type  = M.<typeof >;

type  = M.<typeof >;
type  = M.<typeof >;

Connect to MongoDB

import {  } from "mongster";

await .("mongodb://127.0.0.1:27017/todolist", {
  : { : true }, // Automatically sync indexes from your schema definitions
});

On production, you may want to turn off autoIndex to not hammer the indexing every time your server starts.

Create some documents

Let's create a user and some todo's against that user document.

Creating a user

import {  } from "./models";

const  = await .({
  : "Ishmam Rahman",
  : "ishmam@yahoo.com",
});

Creating todos

const  = await .([
  {
    : .,
    : "Buy groceries",
  },
  {
    : .,
    : "Cook",
  },
]);

.([0].); // Should print `false`

Query Todos with Populate

// Find all incomplete todos
const  = await .({ : false })
  .(["title", "createdAt"])
  .({ : -1 })
  .(10);

// You can also populate the user reference with proper type casting!
const  = await .({ : true })
  // prettier-ignore
  .("userId", {
    : ["name", "email"],
    : false,
  });

Aggregations

You can also do typed aggregations with your models. Let's query a leaderboard based on completed todos.

const  = await .()
  .({ : true })
  .("$userId", {
    : { : 1 },
  })
  .({
    : ,
    : "_id",
    : "_id",
    : "user",
  })
  .("$user")
  .({
    : "$user.name",
    : "$user.email",
    : 1,
  })
  .({ : -1 });

Keep in mind that not all aggregation pipeline is supported by the typed builder methods. If your use-case needs more than what the library provides, you can use the aggregation().raw() method with your own type-casting.

Update and Delete

// Mark a todo as complete
const  = await .(
  { :  },
  {
    : { : true },
  },
);
.(?.); // should be 1 if succeeds

// Or use findOneAndUpdate to get the updated document
const  = await .(
  { :  },
  { : { : true } },
);
.(?.); // should be true

// Delete a todo
const  = await .({ :  });

// Delete all completed todos
await .({ : true });

Congrats! That is the basics of Mongster.

For more cool stuff, read through the docs.

On this page