mirror of
https://github.com/LeCoupa/awesome-cheatsheets.git
synced 2026-01-27 13:48:01 -08:00
246 lines
6.2 KiB
JavaScript
246 lines
6.2 KiB
JavaScript
/* *****************************************************************
|
|
* 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
|
|
},
|
|
},
|
|
];
|