mirror of
https://github.com/LeCoupa/awesome-cheatsheets.git
synced 2026-01-27 21:58:02 -08:00
Merge aa488b84d3 into 10872e02d1
This commit is contained in:
245
databases/mongoose.js
Normal file
245
databases/mongoose.js
Normal file
@@ -0,0 +1,245 @@
|
||||
/* *****************************************************************
|
||||
* Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.
|
||||
* Mongoose supports both promises and callbacks.
|
||||
* ****************************************************************/
|
||||
|
||||
// Import Mongoose
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
/* *****************************************************************
|
||||
List of Mongoose Data Types:
|
||||
String
|
||||
Number
|
||||
Date
|
||||
Buffer
|
||||
Boolean
|
||||
Mixed
|
||||
ObjectId
|
||||
Array
|
||||
Decimal128
|
||||
Map
|
||||
Schema
|
||||
UUID
|
||||
******************************************************************/
|
||||
|
||||
/* *****************************************************************
|
||||
* Schema
|
||||
* A schema is a blueprint for a model.
|
||||
* It defines the structure of the document, default values, validators, etc.
|
||||
* ****************************************************************/
|
||||
|
||||
// Define schema for the a collection
|
||||
const productSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
immutable: true, // This field cannot be changed after creation
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
min: 0, // Minimum value is 0
|
||||
max: 10000, // Maximum value is 10000
|
||||
required: true, // Not specifying a required field will result in validation error
|
||||
},
|
||||
category: {
|
||||
type: String,
|
||||
enum: ["fruit", "vegetable", "dairy"], // Only these values are allowed for 'category'
|
||||
},
|
||||
tags: [
|
||||
// Array of String
|
||||
{
|
||||
type: String,
|
||||
minLength: 2, // Minimum length of a single tag is 2
|
||||
maxlength: 10, // Maximum length of a single tag is 10
|
||||
},
|
||||
],
|
||||
createdAt: {
|
||||
type: Date,
|
||||
// WRONG!
|
||||
// default: Date.now(), // This results in the current date being set (as a static value) when the schema is compiled
|
||||
|
||||
// Correct!
|
||||
default: () => Date.now(), // We instead use a getter function that returns the current date when called
|
||||
},
|
||||
});
|
||||
|
||||
// Create a model from the schema
|
||||
const Product = mongoose.model("Product", productSchema);
|
||||
// We can now use the model to create new documents in the 'products' collection
|
||||
|
||||
/* *****************************************************************
|
||||
* Promises
|
||||
* ****************************************************************/
|
||||
|
||||
Product.create({
|
||||
name: "guava",
|
||||
price: 10,
|
||||
category: "fruit",
|
||||
tags: ["green", "sweet", "fresh"],
|
||||
});
|
||||
|
||||
Product.insertMany([
|
||||
{
|
||||
name: "apple",
|
||||
price: 5,
|
||||
category: "fruit",
|
||||
tags: ["red", "sweet"],
|
||||
},
|
||||
{
|
||||
name: "banana",
|
||||
price: 3,
|
||||
category: "fruit",
|
||||
tags: ["yellow", "sweet"],
|
||||
},
|
||||
{
|
||||
name: "broccoli",
|
||||
price: 2,
|
||||
category: "vegetable",
|
||||
tags: ["green", "healthy"],
|
||||
},
|
||||
{
|
||||
name: "milk",
|
||||
price: 4,
|
||||
category: "dairy",
|
||||
tags: ["white", "healthy"],
|
||||
},
|
||||
]);
|
||||
|
||||
Product.find(); // Get documents in 'product' colelction
|
||||
|
||||
Product.find({ name: "guava" }); // Get documents where name = 'guava'
|
||||
|
||||
Product.find({ price: { $gt: 5, $lt: 10 } }); // Get documents where 5 < price < 10
|
||||
|
||||
Product.find({ name: "banana" }).select({ name: 1, price: 1 }); // Get documents where name = 'banana' and only return name and price
|
||||
|
||||
Product.countDocuments({ category: "vegetables" }); // Get count of documents where category = 'vegetables'
|
||||
|
||||
Product.updateOne({ name: "guava" }, { price: 15 }); // Update the price of the document where name = 'guava' to 15
|
||||
|
||||
Product.deleteOne({ name: "guava" }); // Delete the document where name = 'guava'
|
||||
|
||||
Product.deleteMany({ category: "fruit" }); // Delete all documents where category = 'fruit'
|
||||
|
||||
/* *****************************************************************
|
||||
* Aggregation
|
||||
* The aggregation pipeline refers to a specific flow of operations that processes, transforms, and returns results.
|
||||
* In a pipeline, successive operations are informed by the previous result.
|
||||
* Check out the MongoDB documentation at: https://www.mongodb.com/docs/manual/aggregation/
|
||||
* ****************************************************************/
|
||||
|
||||
// * $match
|
||||
// The following aggration pipeline returns all products where price > 80 AND price < 120.
|
||||
let pipeline = [
|
||||
{
|
||||
$match: {
|
||||
price: {
|
||||
$gt: 80,
|
||||
$lt: 120,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// or you can use:
|
||||
pipeline = [
|
||||
{
|
||||
$match: {
|
||||
price: {
|
||||
$and: [{ $gt: 80 }, { $lt: 120 }],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// Similarly, you can use $or:
|
||||
pipeline = [
|
||||
{
|
||||
$match: {
|
||||
category: {
|
||||
$or: [{ $eq: "fruit" }, { $eq: "vegetable" }],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// * $group
|
||||
// The following aggregation pipeline returns the total number of products created less than a year ago, in each category.
|
||||
pipeline = [
|
||||
{
|
||||
$match: {
|
||||
date: {
|
||||
$gte: new Date(new Date().setFullYear(new Date().getFullYear() - 1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: "$category",
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// * $sort
|
||||
// The following aggregation pipeline returns top 10 most expensive products.
|
||||
// Note: The $sort stage must come before $limit.
|
||||
pipeline = [
|
||||
{
|
||||
$sort: {
|
||||
price: -1,
|
||||
},
|
||||
},
|
||||
{
|
||||
$limit: 10,
|
||||
},
|
||||
];
|
||||
|
||||
// * $project
|
||||
// To get the name and price of all products along with their ObjectId:
|
||||
pipeline = [
|
||||
{
|
||||
$project: {
|
||||
name: 1,
|
||||
price: 1,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// or you can exclude all other fields:
|
||||
pipeline = [
|
||||
{
|
||||
$project: {
|
||||
category: 0, // 0 means exclude
|
||||
tags: 0,
|
||||
date: 0,
|
||||
},
|
||||
},
|
||||
];
|
||||
// Note: You may not use both 0 and 1 in the same projection
|
||||
// other than _id, which is included by default:
|
||||
pipeline = [
|
||||
{
|
||||
$project: {
|
||||
_id: 0, // exclude ObjectId as well
|
||||
name: 1,
|
||||
price: 1,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// * $unwind
|
||||
// The following aggregation returns a new document for 'guava' for each of its tags.
|
||||
pipeline = [
|
||||
{
|
||||
$match: {
|
||||
name: "guava",
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: "$tags", // Name of array field that we want to unwind
|
||||
includeArrayIndex: "arrayIndex", // This will add a new field 'arrayIndex' to each document
|
||||
preserveNullAndEmptyArrays: true, // This will return a document for each tag, even if the 'tags' is null or empty
|
||||
},
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user