MongoDB Flashcards
What is MongoDB?
MongoDb is a NoSQL database.
A mongo database is built of collections (which translate to SQL tables), and documents (which translate to Rows).
Features:
- Document based (Mongo stores data in documents (field-value pair data structures))
- Scalable (Very easy o distribute data across multiple macheines as the users grow)
- Flexible (No document data schema require, so each document can have different number and type of fields)
- Performant (thanks to things like Embedded data models, indexing, sharding, flexible documents, native duplication)
What is BSON?
Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON just like JSON supports the embedding of documents and arrays within other documents and arrays.
The real difference is that BSON values are typed.
The max size of a BSON document is 16mb
What is Embedding/Denormalizing?
It is a process of including related data into a single document. This allows for quicker access and easier data models (however it’s not always the best solution).
The opposite of embedding is normalizing -> In relational databases, this is how the data is always modelled.
How do you checkout/create a DB in mongo shell?
use dbName
if the db is existing - it will switch to the selected database, otherwise it will create a new database.
How do you insert documents to a collection?
db. .insertMany() // and we pass a JS object - it will convert it into JSON and BSON.
db. .insertOne()
How do you view, documents/ collections databases in mongodb shell
db.tours.find()
show dbs
show collections
How do you query for exact match in MongoDB?
You query the collections, by db.tours.find and passing a filter object like:
db.tours.find({difficulty: “easy”})
How do you query with operators in MongoDB?
We pass a mongo operator nested as the object for the values we are searching for.
db.tours.find({price: {$lte: 500}})
How do you add AND to a query?
You just simply pass the key, as another parameter in the filter query. Like:
db.tours.find{price: {$lte: 500}, rating: {$gt: 4.7} }
How do you add an OR operator in MongoDB?
db.tours.find({$or: [{difficulty: “easy”}, {rating: {$lte: 4.8}}]})
What is a Projection?
By default, queries in MongoDB return all fields in matching documents. To limit the amount of data that MongoDB sends to applications, you can include a projection document to specify or restrict fields to return.
Projection simply means, that we want to select some fields in the output.
In order to add projection to the query, we need to pass another object in the query
db.tours.find({$or: [{difficulty: “easy”}, {rating: {$lte: 4.8}}]}, {name: 1})
Result, will be only names of the matching documents
How do you update documents?
db.tours.updateOne({name: “The Snow Adventurer”, {$set: {price: 597} }})
updateOne, even if it matches multiple documents, will update just one. If we want to update many documents, we should use updateMany function.
updateMany and updateOne, will update the fields that we specify in the $set operator, we can however switch the whole document we could use replaceOne or replaceMany functions
(similar to PUT, PATCH).
Deleting documents in MongoDB
db.tours.deleteMany({ rating: {$lt: 4.8}})
we can deleteOne or deleteMany documents, as a parameter we need to specify the filter object.
If we want to delete all documents in a collection, we need to pass an empty object.
db.tours.deleteMany({})
(the empty object is basically a condition that all the documents always match).
How do you connect to a MongoDB with Express app?
In server.js, which is the main file for starting the app, we have references to
app.js (express app and middlewares),
environment variables (dotenv package)
and mongoose()
we need to mongoose.connect(connection_string, { useNewUrlParser: true, useCreateIndex: true, useFindAndModify: false });
and as an argument we pass a connection string and an options object.
IF we are connecting through mongoDB Atlas, we will be provided with that query string.
If we are hosting the DB locally, we will need to build the connection string like: mongodb://localhost:/27017/db_name
Saving to mongoDB using Mongoose
In order to save to mongodb, we need to
1. const mongoose= require(‘mongoose’);
2. const Store = mongoose.model(‘Store’) // import the store schema, that we defined eariler.
3. In the middleware that handles POST request
a. Instantiate the schema
const store = new Store(req.body)
store.save();
we can also store the response object that we get when we await the save, by wrapping the function and chaining the save() method.
const store = await (new Store(req.body)).save()
What is mongoose?
Mongoose is an Object Data Modeling (ODM) Library for MongoDB and Node.js, providing a higher level of abstraction.
- schemas to model data and relationshipts
- easy data validation
- simple query api
- middleware
Mongoose schema: where we model our data by describing the structure of the data, default values, and validation.
Mongoose model: a wrapper for the schema, providing an interface to the database for CRUD operations.
How do you set up a strict Schema in mongo db with Mongoose?
In order to set up a strict schema, in our models folder we should create a schema file. const mongoose = require('mongoose') const mongoose.Promise = global.Promise;
set up a schema by instantiating a new mongoose.Schema, As an argument, we pass a schema object, where we specify fields and type of the data const tourSchema = new mongoose.Schema({ name: { type: String, required: [true, 'A tour must have a name'], unique: true }, rating: { type: Number, default: 4.5 }, price: { type: Number, required: [true, 'A tour must have a price'] }, summary: { type: String, trim: true }, });
module.exports = mongoose.model(‘Store’, storeSchema);
Then this model needs to be imported on app startup.
require(‘./models/Store)
How do you create documents using Mongoose?
The best solution is to create an async function that will be located in the controllers folder.
Based on the Schema we can create an object in the database.
const newTour = await Tour.create(req.body);
res.status(201).json({
status: ‘success’
data: {
tour: newTour
}
}
In order to handle errors, as usual with async/await funcitons, we should wrap the functions with try catch block (or create a catchAsync function)
How do you read documents with Mongoose?
In order to read documents from the MongoDB database, we need to use
Tour.find() function, just like in MongoDB query.
We can of course pass a query string as an argument of the function and that will filter out the results.
There are many helper mongoose methods, that help us to findById, or findByIdAndUpdate, if we will be using another operations.
How do you update documents with mongoose
You update a single document using findByIdAndUpdate(id, obj, {});
In the arguments, you pass the id, that you would like to query, then the data that we want to change, and the optiosn object.
- In the options object we can define that the returned document, will include the updated info, by adding new:true, to the options object,
- We can also define if we want to runValidators: true
const tour = await const tour = await Tour.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
Deleting documents in mongoose
In order to delete a document,
we need to await Tour.findByIdAndDelete(req.params.id)
and handle success and erros with try and catch blocks.
In REST API it is common practice to return nothing in the DELETE operation.
res.status(204).json({ status: 'success', data: null, });
What are the most popular Schema types options?
required: boolean or function, if true adds a required validator for this property
default: Any or function, sets a default value for the path. If the value is a function, the return value of the function is used as the default.
unique: boolean, whether to define a unique index on this property.
select: boolean, specifies default projections for queries
validate: function, adds a validator function for this property
STRING
trim: boolean, whether to always call .trim() on the value
What is the standard way of writing a query string including gte, or lte operators?
In the query string we need to add another part to the key-value pair.
The standard way is to include the operators in the square brackets.
duration[gte]=5
The object that we receive in req.query is almost identically mongoDB filter object, the only thing it is missing is the $ mongo db operator.
localhost:3000/api/v1/tours?duration[gte]=5&price[gt]=1500