Mongoose
Mongoose is an NPM package that allows a simple and schema'd Javascript entrypoint to your Mongo database.
Basics
Setup
Install mongoose: npm i mongoose
and ensure your database is running.
Project
Create a new file called server.js
and put this within.
// Initilize database
const mongoose = require("mongoose");
const dbName = "test";
mongoose.connect(`mongodb://localhost:27017/${dbName}`, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// Create test schema
const testSchema = new mongoose.Schema({
name: String,
age: Number,
friends: [String],
});
// Create a model from your schema
// this first param is the name of your collection in your test database
const Test = mongoose.model("test", testSchema);
// Connect to database
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => {
console.log(`Mongoose DB "${dbName}" initialized\n`)
});
This will have created your basics. You can now start creating queries, inserting items into your database, etc.
Schemas and Models
Basic schemas are written very simply using a standard JSON format.
The following schema is for a registration form. It has five fields, all with differing implementations. Most basic, you can just put the key followed by it's type. If you want extended functionality, you can utilize it by using object notation.
const attendeeSchema = new mongoose.Schema({
firstName: {
type: String,
required: true,
},
lastName: String,
email: {
type: String,
required: true,
match: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/,
},
shirt: {
type: String,
enum: ['XS', 'S', 'M', 'L', 'XL', 'XXL'],
required: true,
},
skillLevel: {
type: String,
enum: ['beginner', 'intermediate', 'expert'],
}
});
Once your schema is created, you will then create a model that will be utilized within your code.
// mongoose.model(collection, schema), where collection is the
// name of the collection in your database.
const Attendee = mongoose.model('attendee', attendeeSchema);
This makes it easy to encapsulate the whole thing inside of a file for export in a node project.
const mongoose = require('mongoose');
const attendeeSchema = new mongoose.Schema({
...
});
const Attendee = mongoose.model('Attendee', attendeeSchema);
module.exports = Attendee;
Querying a Model[4-5]
Depending on how you want to handle the results, you can either return a promise or use a callback.
// Promise
const result = await Attendee.findOne({ name: 'John' }).exec();
const results = await Attendee.find({ name: 'John' }).exec();
// Callback
const result = Attendee.findOne({ name: 'John' }, (err, res) => { /* ... */ });
const results = Attendee.find({ name: 'John' }, (err, res) => { /* ... */ });
When the database gets queried by Mongoose, the return values are special objects that include helpful methods and other stuff. If you only want the JSON returned back, you can finish the query with a call to lean
instead of exec
.
// Promise
const result = await Attendee.findOne({ name: 'John' }).lean();
// Callback
const result = Attendee.findOne({ name: 'John' }).lean().exec((err, res) => {});
Populating a Model/Table Joins
In defining a schema, you can set a ref
that will allow you to pull related data easily from another table.
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
const postSchema = newmongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
content: String,
});
const User = mongoose.model('User', userSchema);
const Post = mongoose.model('Post', postSchema);
When querying this, we have to use the populate
command to grab the field we want to be populated/joined. The argument it takes is the name of the field we want populated.
const queriedPost = await Post.findOne().populate('user').exec();
/*
resulting object with "existing" data:
{
user: {
username: "Bob",
password: "RobertIsCool",
},
content: "A cool post",
}
*/
Remote Database
mongoose.connect('mongodb://username:password@host:port', {useNewUrlParser: true});
Troubleshooting
Return Object
The return of a query is not a plain Javascript object and will show weird behavior when trying to add to/remove from/modify it. If you want a plain Javascript object in return, you can use .lean()
within your chain to cast it.
References
- https://mongoosejs.com/
- https://stackoverflow.com/questions/33614229/how-to-use-mongo-mongoose-to-connect-to-a-remote-database
- https://mongoosejs.com/docs/connections.html
- https://mongoosejs.com/docs/api.html#model_Model-find
- https://stackoverflow.com/a/41148831/14857724
Incoming Links
Last modified: 202401040446