Mongo

Mongo module built with appolo-mongo and mongoose

Installation#

npm i @appolo/mongo

Options#

keyDescriptionTypeDefault
idModelRepository injection idstringmodelRepository
connectionmongo connection stringstringnull
configmongose connection optionsobject{}
exitOnDisconnect`call process.exit on disconnectbooleanfalse `

Default Connections Options#

keyDefault
keepAlivetrue
useNewUrlParsertrue
useCreateIndextrue
autoReconnecttrue
reconnectTriesNumber.MAX_VALUE
reconnectInterval500

in config/modules/all.ts

import {MongoModule} from '@appolo/mongo';
export = async function (app: App) {
app.module.use(MongoModule.for({
connection:"mongo://mongo-connection-string"
}));
}

Usage#

import {define, singleton} from '@appolo/inject'
import {schema,prop,Model,model,Ref,injectModel,Doc} from "@appolo/mongo";
@model()
@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
@prop(Address)
address:Address
}
@schema()
export class Address extends Schema{
@prop({type:String})
street:string
@prop({type:String})
city:string
}
@model()
@schema()
export class Comment extends Schema{
@prop({type:String})
text:string
@prop({ref:User})
user:Ref<User>
}
@define()
@singleton()
export class SomeManager {
@model(User) userModel:Model<User>;
async getUser(id:string): Promise<Doc<User>> {
let user = await this.userModel.findById(id)
return user;
}
}

Schema#

options#

@schema(collectionName:string,options:SchemaOptions)#

define new schema with collectionName and mongose schema options

@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
@prop(Address)
address:Address
}

prop#

The prop decorator define class property to the Mongoose schema as a property

@prop({ type:String })
firstName: string;

sub document#

define sumDocument

@schema()
export class Address extends Schema{
@prop({type:String})
street:string
@prop({type:String})
city:string
}
@schema()
export class User extends Schema{
@prop(Address)
address:Address
}

ref#

add a ref to another mongoose schema the ref schema must be defined as model with model

@model()
@schema()
export class User extends Schema{
@prop()
name:string
}
@model()
@schema()
export class Comment extends Schema{
@prop({ref:User})
user:Ref<User>
}

arrays#

define any field as array using []

@prop([ type: String ])
names?: string[];
@prop([Address])
addresses:Address[]
@prop([{ref:User}])
user:Ref<User>[]

required#

define required field

@prop({ type:String ,required:true})
firstName: string;

index#

define index field

@prop({ index: true })
name?: string;

unique#

define unique field

@prop({ unique: true })
someId?: string;

enum#

define enum field

enum Gender {
MALE = 'male',
FEMALE = 'female',
}
@prop({ enum: Gender })
gender?: Gender;

default#

define field with default

@prop({ type: String,default:"myName" })
name?: string;

validate#

validate using minlength / maxlength / match / min /max same as mongoose

@prop({ minlength: 5, maxlength: 10, match: /[0-9a-f]*/ })
phone: string;

custom validate#

or use custom validator same as mongoose

@prop({
type: String,
validate: {
validator: function(v) {
return /\d{3}-\d{3}-\d{4}/.test(v);
}
},
message: props => `${props.value} is not a valid phone number!`
})
phone: string;

virtual#

define virtual getter setters as in mongoose

@prop()
firstName?: string;
@prop()
lastName?: string;
@virtual() // this will create a virtual property called 'fullName'
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
set fullName(full:string) {
const [firstName, lastName] = full.split(' ');
this.firstName = firstName;
this.lastName = lastName;
}

static method#

define static method as in mongoose the method will be created on the mongose model

@staticMethod()
static findByName(this: Model<User>, name: string) {
return this.findOne({ name });
}
@define()
@singleton()
export class SomeManager {
@model(User) userModel:Model<User> & typeof User;
async getUser(name:string): Promise<Doc<User>> {
let user = await this.userModel.findByName(name)
return user;
}
}

you need added the typeof User in order to use the static method findByName

instance Method#

define instance method as in mongoose instance methods are created on mongoose document

@method()
addAge(this: Doc<User>,age?:number) {
this.age = this.age + (age ||1 );
return this.save();
}

pre#

define mongoose pre hooks the pre function will be executed before the defined hook

@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
@pre("save")
private preSave(this:Doc<User>,next){
if (this.name === 'aaa') {
this.name = 'bbb';
}
next();
}
}

post#

define mongoose post hooks the post function will be executed after the defined hook

@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
@post("save")
private preSave(doc:Doc<User>,next){
console.log('%s has been saved', doc._id);
next();
}
}

Model#

define model#

register new schema model

@model()
@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
}

inject model#

inject model to class

@define()
@singleton()
export class SomeManager {
@model(User) userModel:Model<User>;
async getUser(id:string): Promise<Doc<User>> {
let user = await this.userModel.findById(id)
return user;
}
}

Schema Api#

collectionName#

get the defined collection name on schema

@model()
@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
}
User.collectionName // "user"

getSchema#

return mongoose schema object

@model()
@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
}
let schema = User.getSchema()

getModel#

define and mongoose model instance by mongoose connection

@model()
@schema("User",{strict:true})
export class User extends Schema{
@prop({type:String})
name:string
}
let model = User.getModel<User>(mongoose.connection)
model.findById("someId")

ModelRepository#

with modelRepository you can access to the mongoose connection and all the models

connection#

getter return mongoose connection

getModel#

getModel<T>(model: typeof Schema): Model<T>#

return mongoose model by schema type

@define()
@singleton()
export class SomeManager {
@inject() modelRepository:ModelRepository;
async getUser(id:string): Promise<Doc<User>> {
let user = await this.modelRepository.getModel(User).findById(id)
return user;
}
}