TypeScript is an object-oriented programming language, and it is a superset of JavaScript and contains all of its elements. By using TSC (TypeScript Compiler), we can convert Typescript code (.ts file) to JavaScript (.js file). It is open-source and its code is easier to read and understand.
MongoDB is a versatile widely used NoSQL documentation based database. A collection can hold a bunch of documents. We can assume a collection as a table in RDBMS technology, but no strong entity relationships are required in the collection. A mongoose schema is equivalent to a collection. We can keep different data inside a Mongoose schema to create the collection in MongoDB. In this article, let us see how to make Mongo schema from pure Typescript class. The extension of the Typescript file is .ts and usually, from Angular framework projects, we are using Typescript classes, and let us see in detail. In order to interact with MongoDB, we require Mongoose.
Project Setup and Module Installation:
Step 1: We are going to use the Typescript class, let us create by initializing a project using the following command.
yarn init (or npm init )
When prompted, set the entry point to the following file.
src/server.ts .
Step 2: Install the required module using the following command.
# Dependency to connect to create MongoDB
# Schema and connect to mongodb
yarn add express mongoose
# Dependency to create TypeScript files,
# Dependency to execute those files in Node
# Dependency to speed up the development
yarn add -D nodemon typescript ts-node
@types/express @types/mongoose @types/node
# GlobalDependencies
npm i -g typescript ts-node
package.json: Our package.json file will look like this.
{
"name": "mongo-typescript",
"version": "1.0.0",
"main": "src/server.ts",
"license": "MIT",
"scripts": {
"start": "node --inspect=5858 -r ts-node/register ./src/server.ts",
"dev": "nodemon",
"build": "tsc",
"script": "cd src/scripts && ts-node"
},
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.9.7"
},
"devDependencies": {
"@types/express": "^4.17.6",
"@types/mongoose": "^5.7.10",
"@types/node": "^13.11.1",
"nodemon": "^2.0.3",
"ts-node": "^8.8.2",
"typescript": "^3.8.3"
}
}
tsconfig.json: This file has to be created in the root directory, and it will tell the compiler about the location for TypeScript files, and it will allow us to use ES6 import/export syntax.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "dist",
"sourceMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", ".vscode"]
}
Connecting to the Database: For database connectivity, Create a separate folder using the following commands.
mkdir src
cd src
mkdir database
touch database.ts
Project Structure: It will look like this.
Example:
database.ts
import * as Mongoose from 'mongoose' ;
import { EmployeeModel } from './employees/employees.model' ;
let database: Mongoose.Connection;
export const connect = () => {
const uri =
if (database) {
return ;
}
Mongoose.connect(uri, {
useNewUrlParser: true ,
useFindAndModify: true ,
useUnifiedTopology: true ,
useCreateIndex: true ,
});
database = Mongoose.connection;
database.once( 'open' , async () => {
console.log( 'Connected to database successfully' );
});
database.on( 'error' , () => {
console.log(`Error connecting to database. Check Whether mongoDB
installed or you can try to give opensource Mongo Atlas database`);
});
return {
EmployeeModel
};
};
export const disconnect = () => {
if (!database) {
return ;
}
Mongoose.disconnect();
};
|
server.ts
import * as express from "express" ;
import { connect } from "./database/database" ;
const app = express();
const port = 5002;
connect();
app.listen(port, () => {
console.log(`Server started on http:
});
|
Create models
Typescript files are helpful to create Mongo Schema. It is mentioned as Three parts to a Mongoose model (schema, static methods, and instance methods), Fourth one is to hold our TypeScript interfaces, and the fifth to bring everything together.
Inside the src/database/<collectionname> folder, let us create the models. Here <<collectionname> represents the name of MongoDB collection. Let us have it as employees.
- <collectionname>.schema.ts: Define the Mongoose Schema, which helps for the determination of the shape of our MongoDB documents.
- <collectionname>.statics.ts: Required static methods are added and called on the model itself.
- <collectionname>.methods.ts: Instance methods of our model, functions which can be called on individual model instances.
- <collectionname>.types.ts: Store the types we’ll use in the other files.
- <collectionname>.model.ts: It is used to combine everything together.
We can use the following command to create a directory and files.
# Move to scr folder and create database folder
cd src
mkdir database
# Move to database folder and create employees folder
cd database
mkdir employees
# Move to employees folder and create files
cd employees
touch employees.schema.ts employees.statics.ts
touch employees.methods.ts employees.types.ts employees.model.ts
employees.schema.ts
import * as Mongoose from "mongoose" ;
const EmployeeSchema = new Mongoose.Schema({
firstName: String,
lastName: String,
age: Number,
dateOfJoining: {
type: Date,
default : new Date(),
},
lastUpdated: {
type: Date,
default : new Date(),
},
gender: String,
department: String,
});
export default EmployeeSchema;
|
- IEmployeeDocument: Inclusion of our fields and other elements of a standard Mongoose Document.
- IEmployeeModel: Representation of a standard Mongoose Model, containing documents of our IEmployeeDocument type.
employees.types.ts
import { Document, Model } from "mongoose" ;
export interface IEmployee {
firstName: string;
lastName: string;
age: number;
dateOfEntry?: Date;
lastUpdated?: Date;
gender: String;
department: String;
}
export interface IEmployeeDocument extends IEmployee, Document { }
export interface IEmployeeModel extends Model<IEmployeeDocument> { }
|
employees.model.ts
import { model } from "mongoose" ;
import { IEmployeeDocument } from "./employees.types" ;
import EmployeeSchema from "./employees.schema" ;
export const EmployeeModel = model<IEmployeeDocument>( "employee" ,
EmployeeSchema
)
|
Create two static methods as shown below:
- findOneOrCreate: Checks for an entry for its existence and if not, creates a new entry.
- findByAge: Returns an array of employees, based on a provided age range.
Similarly, we can define methods depends upon the requirement like findByGender, findByDepartment, etc., which ultimately matches our requirements
employees.statics.ts
import { IEmployeeDocument, IEmployeeModel } from "./employees.types" ;
export async function findOneOrCreate(
this : IEmployeeModel,
{
firstName,
lastName,
age,
gender,
department,
}: {
firstName: string; lastName: string; age: number;
gender: string; department: string
}
): Promise<IEmployeeDocument> {
const employeeRecord = await this .findOne({
firstName,
lastName, age, gender, department
});
if (employeeRecord) {
return employeeRecord;
} else {
return this .create({
firstName, lastName,
age, gender, department
});
}
}
export async function findByAge(
this : IEmployeeModel,
min?: number,
max?: number
): Promise<IEmployeeDocument[]> {
return this .find({ age: { $gte: min || 0, $lte: max || Infinity } });
}
|
employees.methods.ts
import { Document } from "mongoose" ;
import { IEmployeeDocument } from "./employees.types" ;
export async function setLastUpdated(
this : IEmployeeDocument): Promise<void> {
const now = new Date();
if (! this .lastUpdated || this .lastUpdated < now) {
this .lastUpdated = now;
await this .save();
}
}
export async function sameLastName(
this : IEmployeeDocument): Promise<Document[]> {
return this .model( "employee" )
.find({ lastName: this .lastName });
}
|
employees.schema.ts
import * as Mongoose from "mongoose" ;
import { findOneOrCreate, findByAge } from "./employees.statics" ;
import { setLastUpdated, sameLastName } from "./employees.methods" ;
const EmployeeSchema = new Mongoose.Schema({
firstName: String,
lastName: String,
age: Number,
dateOfJoining: {
type: Date,
default : new Date(),
},
lastUpdated: {
type: Date,
default : new Date(),
},
gender: String,
department: String,
});
EmployeeSchema.statics.findOneOrCreate = findOneOrCreate;
EmployeeSchema.statics.findByAge = findByAge;
EmployeeSchema.methods.setLastUpdated = setLastUpdated;
EmployeeSchema.methods.sameLastName = sameLastName;
export default EmployeeSchema;
|
employees.types.ts
import { Document, Model } from "mongoose" ;
export interface IEmployee {
firstName: string;
lastName: string;
age: number;
dateOfJoining?: Date;
lastUpdated?: Date;
gender: String;
department: String;
}
export interface IEmployeeDocument extends IEmployee, Document {
setLastUpdated: ( this : IEmployeeDocument) => Promise<void>;
sameLastName: ( this : IEmployeeDocument) => Promise<Document[]>;
}
export interface IEmployeeModel extends Model<IEmployeeDocument> {
findOneOrCreate: (
this : IEmployeeModel,
{
firstName,
lastName,
age,
gender,
department,
}: { firstName: string; lastName: string; age: number;
gender: string; department: string; }
) => Promise<IEmployeeDocument>;
findByAge: (
this : IEmployeeModel,
min?: number,
max?: number
) => Promise<IEmployeeDocument[]>;
}
|
sampleEmployeeData.ts
import { EmployeeModel } from "../database/employees/employees.model" ;
import { connect, disconnect } from "../database/database" ;
(async () => {
connect();
const employees = [
{
firstName: "Rachel" , lastName: "Green" , age: 25,
gender: "Female" , department: "Design"
},
{
firstName: "Monica" , lastName: "Geller" , age: 25,
gender: "Female" , department: "Catering"
},
{
firstName: "Phebe" , lastName: "Phebe" , age: 25,
gender: "Female" , department: "Masus"
},
{
firstName: "Ross" , lastName: "Geller" , age: 30,
gender: "Male" , department: "Paleontology"
},
{
firstName: "Chandler" , lastName: "Bing" , age: 30,
gender: "Male" , department: "IT"
},
{
firstName: "Joey" , lastName: "Joey" , age: 30,
gender: "Male" , department: "Dramatist"
},
];
try {
for (const employee of employees) {
await EmployeeModel.create(employee);
console.log(`Created employee ${employee.firstName}
${employee.lastName}`);
}
disconnect();
} catch (e) {
console.log(e);
}
})();
|
Steps to run the application: Start the server using the following command.
yarn start
The next step is we need to create the collections using the Mongoose schema. Use the following command to fill in the data:
yarn script sampleEmployeeData.ts
Output:
In the Mongo shell, we can verify the same. In UserDB database, on querying db.employees.find().pretty(), we can see the output:
Conclusion: Typescript files are so cool which has advanced features of JavaScript and by using mongoose, Express we can easily create MongoDB schemas by using Typescript files
Last Updated :
08 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...