Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@cameronct/mongo-odm

CameronCT52MIT0.1.92TypeScript support: included

A very basic MongoDB ODM for Node.js

mongo, mongodb, orm, odm, object document mapping, object relational mapping

readme

An insanely basic implementation of some form of Object Document Mapping (not ORM) for MongoDB. This was not really made to be used as a widely available package, it does not contain severely insane levels of logging.

Getting Started

To get started you must install the package via your dependency manager (you can use yarn as well)

npm install @cameronct/mongo-odm

Initiating the Connection

import MongoODM from "@cameronct/mongo-odm";

// Basic
await MongoODM.connect();

// With Connection URI
await MongoODM.connect("mongodb://localhost:27017/my-app");

// With Custom Models Folder
await MongoODM.connect("mongodb://localhost:27017/my-app", path.join(__dirname, "path/to/models"));

Creating a Model

Here is an example Model that can be found in /models/User.js

import MongoODM from "@cameronct/mongo-odm";

const User = new MongoODM.Model("users", [
    { name: "name", type: MongoODM.FieldTypes.String, required: true },
    { name: "email", type: MongoODM.FieldTypes.String, required: true },
    { name: "password", type: MongoODM.FieldTypes.String, required: true },
    { name: "type", type: MongoODM.FieldTypes.String, default: "basic" },
], [ 
    { name: "uniqueEmail", fields: { email: "text" } },
])

Using a Model

Some examples, most native functionality from MongoDB will work here.

import User from "./models/User";

await User.count({ email: "@example.com" });
await User.findOne({ email: "@example.com" });
await User.findOneOrCreate({ email: "@example.com" }, { name: "test", email: "@example.com" });
await User.findOneAndUpdate({ email: "@example.com" }, { name: "test", email: "new@example.com" }, "$set");
await User.insertOne({ name: "test", email: "@example.com" });
await User.updateOne({ email: "@example.com" }, { name: "test", email: "new@example.com" }, "$set");
await User.removeOne({ email: "@example.com" });

Using QueryBuilder

This is not a recommend way of doing my library, as you're essentially doing the same thing as using the native MongoDB driver. However, you can use the QueryBuilder class directly to interact with the Database which will skip the entire Model/Schematic aspect of the library.

The only difference is you will specify the collection name manually, like in the example it's doing the queries in the users collection.

import MongoODM from "@cameronct/mongo-odm";

const queryBuilder = new MongoODM.QueryBuilder();

await queryBuilder.count("users", { email: "@example.com" });
await queryBuilder.findOne("users", { email: "@example.com" });
await queryBuilder.findOneOrCreate("users", { email: "@example.com" }, { name: "test", email: "@example.com" });
await queryBuilder.findOneAndUpdate("users", { email: "@example.com" }, { name: "test", email: "new@example.com" }, "$set");
await queryBuilder.insertOne("users", { name: "test", email: "@example.com" });
await queryBuilder.updateOne("users", { email: "@example.com" }, { name: "test", email: "new@example.com" }, "$set");
await queryBuilder.removeOne("users", { email: "@example.com" });

Documents

When a document is inserted into the collection, we specifically add createdAt field for new documents using insertOne, insertMany and findOneOrCreate. We also add an updatedAt field for new documents using updateOne, updateMany and findOneAndUpdate

These parameters cannot be overridden inside of the Model. I may change this functionality later, but for now it is what it is.

Tests

Inserting 50,000 documents using insertMany. Code for generating documents is below.

function generateTestData() {
    const documents = Array.from({ length: 50000 }, (_, index) => ({
        name: `Student ${index}`,
        age: Math.floor(Math.random() * 100),
    }));

    return documents;
}

Results:

MongoDB Native Test completed in 297 milliseconds
Mongoose Test completed in 1883 milliseconds
MongoODM Test completed in 313 milliseconds

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.1.92] - 2025-01-05

  • Fixed issue with indexes not creating. (#11)

[0.1.91] - 2024-08-20

  • Fixed issue with MongoODM.Connection not allowing custom uri

[0.1.90] - 2024-07-08

  • Updated MongoODM.Connection to use async to prevent further execution of database queries. (#6)
  • Added better jest (still basic) testing that performs database queries now. (#5)
  • Added MongoODM.connect() as a substitute of doing MongoODM.Connection

[0.1.85] - 2024-01-08

  • Removed appending of Model to Connection.$models - it is causing conflict with production environments.

[0.1.84] - 2024-01-08

  • Fixed bug with Model.updateMany where useModifier was not being properly used.
  • Possibly fixed issue where Model loading would throw a "cannot import outside of a module" error.
  • Added checkAndReturnModelPath to check for multiple directories to make sure Models are being fetched in most development and production environments.

[0.1.83] - 2023-12-27

  • Fixed bug with QueryBuilder.find where FindCursor would be returned instead of BSON.Document[]
  • Fixed bug with QueryBuilder.findOneAndUpdate where it would not return the updated document.
  • Added more debugging in /test to properly test more methods between Query Builder and Model instances.

[0.1.82] - 2023-12-27

  • Fixed bug with QueryBuilder.aggregate where the AggregationCursor would be returned instead of the BSON.Document[].

[0.1.81] - 2023-12-26

  • Fixed bug with QueryBuilder.updateOne and QueryBuilder.findOneAndUpdate where it would run processDocument and validate fields that would not exist.

[0.1.8] - 2023-11-18

  • Added FieldTypes.Mixed as a Schema option (#1)
  • Added Jest tests (not conclusive yet)
  • Added QueryBuilder class
    • This will be the backbone to queries inside of Models
    • Also provides an alternative method of just doing queries without going through the Model creation process.
  • Fixed issue with Array types not working (#2)
  • Added Code Coverage reporting and added jests to CI/CD

[0.1.6/0.1.7] - 2023-11-17

  • Renamed project to Mongo-ODM
  • Updated Docs

[0.1.5] - 2023-11-16

  • Added ESLint
  • Added Prettier
  • Added Better Typed definitions to Model
  • Added enhanced documentation (WIP)

[0.1.4] - 2023-11-15

Fixed

  • Issue with method not calling as an async function
  • Removed the force-lowercase of collections