mongocat
v1.2.0
Published
✨ Mongocat 😺 is easy to use, configuration based Denormalization mongoose plugin for read heavy applications. Mongocat reduces write complexity too.
Downloads
27
Maintainers
Readme
Easy to use, configuration based Denormalization mongoose plugin for read heavy applications. Mongocat will reduce your write complexity too.
Installation
npm i mongocat
Why mongocat?
- When a mid scale application are so read heavy and need an emergency solution.
Advantages
application performs well for many requests
easy to find, filter read operations
easy to setup
declarative approach
maintainability - you have to manage configuration only
very easy to sync
frequently requirement change is not nightmare here
Denormalize as you really need
Single source of truth. Third party source of document updates is easily synced by mongocat
Disadvantages
write operations are so slow
too much abstraction- denormalizable operations are hidden from business logic.
write operations are expensive & have to handle sensitively
it's behave like sql for strict mode. If foreign key doesn't exist write operation will fail. ( it's a good advantage for data consistency too )
Requirement
Firstly generate boilerplate & connect to database (mongodb via Mongoose ODM)
Mongoose version must be greater than 6.x.x
For existing project use mongocat-sync to migrate to denormable schema (We are working on it, it's not available yet)
Setup providers & consumers carefully
Follow linear approach, one collection can consume many denormalized data from many provider
A provider can consume many denormalized data from other providers too but never create big bang
Big bang creates when you are consuming from a collection at the same time provider denorbmalized data to that consumer too.
Documentation
Provider
import { provider } from 'mongocat';
const CategorySchema = new Schema(
{
title: String,
slug: String,
icon: String,
status: String,
},
{ timestamps: true }
);
CategorySchema.plugin(
provider({
toRef: 'Category',
keyFields: ['title', 'slug', 'icon'],
ignoredFields: ['status'],
})
);
export const Category = model('Category', CategorySchema);
import { provider } from 'mongocat';
const UserSchema = new Schema(
{
name: String,
username: String,
email: String,
status: String,
},
{ timestamps: true }
);
UserSchema.plugin(
provider({
toRef: 'User',
keyFields: ['name', 'username', 'email', 'status'],
})
);
export const User = model('User', UserSchema);
Consumer
import { watchConsumer } from 'mongocat';
const BlogSchema = new Schema({
title: String,
slug: String,
category: new Schema({
_id: {
type: Schema.Types.ObjectId,
ref: 'Category',
},
title: String,
slug: String,
icon: String,
}),
status: Boolean,
});
BlogSchema.plugin(
watchConsumer({
toPath: 'category',
key: '_id',
strict: true,
fromRef: 'Category',
toRef: 'Blog',
changeStreamEnabled: false, // sync updatesfrom third party source
})
);
export const Blog = model('Blog', BlogSchema);
Frontend Payloads
Blog:
{ title: "Mongocat is joss", category: { _id: "62960300da98cc1aba3e9ee2" }, status: true }
{
title: "Docker is joss",
category: {
_id: "62960300da98cc1aba3e9ee2"
},
tags: [
{ _id: "62960300da98cc1aba3e9ee2" },
{ _id: "62960300da98cc1aba3e9ee2" }
],
status: true
}