mongoose-entity is a class-based wrapper for mongoose that supports new javascript syntax.
Each model should extends MongooseEntity model. MongooseEntity model contains an _id property that will be assigned to passed value or unique identifier generated by default.
var mongoose = require('mongoose-entity').mongoose;
var MongooseEntity = require('mongoose-entity').MongooseEntity;
var createdBy = new WeakMap();
class Entity extends MongooseEntity {
constructor(spec) {
super(spec);
this.createdBy = spec.createdBy;
}
get createdBy() {
return createdBy.get(this);
}
set createdBy(value) {
if(!value || typeof value !== 'string') {
throw 'createdBy prop should be not empty string';
}
createdBy.set(this, value);
}
}
Model can extends another model.
var name = new WeakMap();
var books = new WeakMap();
class User extends Entity {
constructor(spec) {
super(spec);
this.name = spec.name;
this.books = spec.books;
}
get name() {
return name.get(this);
}
set name(value) {
if(!value || typeof value !== 'string') {
throw 'name prop should be not empty string';
}
name.set(this, value);
}
get books() {
return books.get(this);
}
set books(value) {
if(!value || !value.length) {
throw 'books prop should be an array';
}
for(let book of value) {
if(!(book instanceof Book) && !(book instanceof mongoose.Types.ObjectId)) {
throw 'each book should be an instance of Book or a reference to the book';
}
}
books.set(this, value);
}
}
var title = new WeakMap();
var author = new WeakMap();
class Book extends Entity {
constructor(spec) {
super(spec);
this.title = spec.title;
this.author = spec.author;
}
get title() {
return title.get(this);
}
set title(value) {
if(!value || typeof value !== 'string') {
throw 'title prop should be not empty string';
}
title.set(this, value);
}
get author() {
return author.get(this);
}
set author(value) {
if(!(value instanceof User) && !(value instanceof mongoose.Types.ObjectId)) {
throw 'author should be an instance of User or a reference to the user';
}
author.set(this, value);
}
}
DataModel is the class that is used to create data sets (collections) for your DataContext from the specified Model (domain model) and schema (description of the Model). Also, you can pass a custom data set name as a third parameter.
var DataModel = require('mongoose-entity').DataModel;
var entitySchema = {
createdOn: { type: Date, required: true }
};
var userSchema = new mongoose.Schema(Object.assign({
name: { type: String, required: true, unique: true },
books: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Book'}]
}, entitySchema));
var bookSchema = new mongoose.Schema(Object.assign({
title: { type: String, required: true },
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User'}
}, entitySchema));
var userModel = new DataModel(userSchema, User); // data set for users collection
var bookModel = new DataModel(bookSchema, Book, 'books'); // data set for books collection
DataContext is the class that is used to perform any kind of operations with collections and entities.
You should create your own data context implementation to perform operations with your data. Each your data context should extend DataContext singleton class provided by mongoose-entity.
There are special init method, that should be defined in your data context implementation. It should return an array of DataModel instances that are related to this context.
All the DataModels returned by init method will be available as data sets (collections) in the instance.
var DataContext = require('mongoose-entity').DataContext;
class MyContext extends DataContext {
constructor(){
super();
}
init(){
var entitySchema = {
createdOn: { type: Date, required: true }
};
var userSchema = new mongoose.Schema(Object.assign({
name: { type: String, required: true, unique: true },
books: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Book'}]
}, entitySchema));
var bookSchema = new mongoose.Schema(Object.assign({
title: { type: String, required: true },
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User'}
}, entitySchema));
return [
new DataModel(userSchema, User),
new DataModel(bookSchema, Book)
];
}
}
var myDataContextInstance = new MyDataContext(); // create instance each time you need
var usersCollection = myDataContextInstance.users; // users data set
var booksCollection = myDataContextInstance.books; // books data set
To perform any operation or execure query you should get appropriate data set and call appropriate function with appropriate parameters.
// .save(entity), where entity is an instance of appropriate Model.
var context = new MyContext();
var user = new User({ name: 'name' });
var book = new Book({ title: 'title' });
user.books = [book];
var book2 = new Book({ title: 'title2' });
user.books.push(book2);
book.author = user;
book2.author = user;
yield* context.users.save(user);
yield* context.books.save(book);
yield* context.books.save(book2);
// .remove(entity), where entity is an instance of appropriate Model.
yield* context.users.remove(user);
// .findAndRemove(criteria), remove all entities from db those correspond to criteria
yield* context.books.findAndRemove({ title: 'title'});