Mongoose CheatSheet

JS
S
JavaScript

Mongoose Cheat Sheet with examples. Updated frequently. * Mongoose Promises via 'mpromise' (A+ Compliant) https://www.npmjs.com/package/mpromise

1// Filter Empty Arrays
2const allSuppliers = await SupplierModel.find({
3  $and: [
4    { $where: 'this.timeSlots.length > 0' },
5    { $where: 'this.patches.length > 0' },
6    { abbreviation: { $exists: true } }
7  ]
8});
9
10
11// Simple Find Query with Limit
12CapacityAndAvailabilityModel.find().limit(20);
13
14// Query between 2 dates (1 month)
15const begOfMonth = moment().utc().month(month).startOf('month').toISOString();
16const endOfMonth = moment().utc().month(month).endOf('month').toISOString();
17const query = {
18  accountType: type,
19  date: { $gte: begOfMonth, $lte: endOfMonth }
20}
21
22
23// Get document mongo generated timestamp
24const timestamp = moment(transaction._id.getTimestamp());
25
26// Remove element from array
27const query = {
28  transactions: transaction._id
29}
30const updateQuery = { $pull: query };
31Payment.findOneAndUpdate(query, updateQuery)
32  .then(payment => {
33    console.log(payment)
34  })
35  .catch(err =>{
36    throw err;
37  })
38
39// Add element to array
40const query = {
41  transactions: transaction._id
42}
43const updateQuery = { $addToSet: query };
44Payment.findOneAndUpdate(query, updateQuery)
45  .then(payment => {
46    console.log(payment)
47  })
48  .catch(err =>{
49    throw err;
50  })
51
52
53// Populate (nested)
54populate({
55    path: ‘subscription’,
56    model: ‘subscription’,
57    populate: {
58        path: ‘accountId’,
59        model: ‘account’
60    }
61})
62
63
64// FindOneAndUpdate with Promises
65const query = { _id: id };
66const update = { $inc: { rating: 1 } };
67const options = {new: true };
68
69RecipeModel.findOneAndUpdate(query, update, options)
70.then(result => {
71    Logger.log(result, 'receipt updated');
72    res.json({ success: true });
73})
74.catch(err => {
75    next(err);
76});
77
78// Simple Aggregation on a child object
79return Account.aggregate().match({
80  active: true,
81  scheduledTransaction: {
82      $elemMatch: {
83          dateKey: {
84              $gte: start,
85              $lt: end
86          },
87          textKey: {
88              $exists: false
89          }
90      },
91  }
92})
93
94// Simple Aggregation on a child object (with not operator)
95return Account.aggregate().match({
96  active: true,
97  scheduledTransaction: {
98      $not : {
99          $elemMatch : {
100              provider: 'Manual'
101          }
102      }
103  }
104})
105
106
107// Update Object key
108Model.update(
109  {name: 'Koka'}, 
110  {$set: {'address.street': 'new street name'}}, 
111  callback);
112
113// SCHEMAS AND MODELS 
114// ============================================================================================
115const mongoose = require('mongoose');
116const Schema = mongoose.Schema;
117
118//  Conditionally Transform schema on runtime
119const toMutateSchema = new Schema();
120toMutateSchema.add({
121    memberName: String
122});
123toMutateSchema.add({
124    newField: String
125});
126
127const telemetrySchema = new Schema({
128    name: String,
129    project: String,
130    createdOn: {
131        type: Date,
132        default: Date.now
133    }
134});
135const Telemetry = mongoose.model('Telemetry', telemetrySchema);
136module.exports = Telemetry;
137
138// Create a document and save
139const Telemetry = require('./telemetry');
140const doc = new Telemetry({
141     name: 'John',
142     project: 'clicks'
143});
144doc.save((err) => {
145    if(err) { return handleError(err) };
146});
147
148// Do not allow mongoose to generate an Id
149const noIdSchema = new Schema({
150   _id:false,
151   name: String
152});
153
154
155// GET QUERIES 
156// ============================================================================================
157const conditionalQuery = Telemetry.find();
158if(condition){
159      conditionalQuery.where({name: filterName})
160}
161query.exec((err,results)=>{
162    if(err) { return handleError(err) };
163    // console.log(results);
164});
165
166const deferredQuery = Telemetry.find();
167deferredQuery.exec((err,data)=>{
168    if(err) { return handleError(err) };
169    // console.log(data);
170});
171
172const immediateQuery = Telemetry.find((err, data) => {
173     if(err) { return handleError(err) };
174    // console.log(data);
175});
176
177const queryParams = Telemetry.find({name: 'Sample'}, (err,data)=> {
178     if(err) { return handleError(err) };
179    // console.log(data);
180});
181
182const queryParamsProjected = Telemetry.find({name: 'Adrian Murray'}, 'name project', (err,data)=> {
183     if(err) { return handleError(err) };
184    // console.log(data);
185});  
186
187// ID
188const id = '5a36e8bebaa42e16d029b497';
189const findById = Telemetry.findById(id, '-project').exec((err,data) => {
190     if(err) { return handleError(err) };
191    // console.log(data);
192});
193
194// Query Operators
195const opFind = Telemetry.find({amount: {$gte:1, $lt:20}}, (err,data)=>{
196     if(err) { return handleError(err) };
197    // console.log('opFind',data);
198});
199
200const opWhere = Telemetry.where('amount').gte(1).lt(2).exec((err, data) => {
201     if(err) { return handleError(err) };
202    // console.log('opWhere', data);
203});
204
205const chainedWhere = Telemetry
206    .where('amount').gte(1).lt(2)
207    .where('project').ne('test')
208    .where('comments', 'Quia iusto officia facere quis enim fugiat duis ad est adipisci eius dolorem ut error')
209    .exec((err,data)=>{
210     if(err) { return handleError(err) };
211        console.log(data);
212    })
213
214
215// UPDATE/REMOVE 
216// ============================================================================================
217// Update directly
218const uOptions = {
219    safe: true, // default to value set in schema
220    upsert: false, // create a new doc if condition not found
221    multi: false, // update multiple docs at the same time
222    strict: false, // 
223    overwrite: false //disable update only mode
224}
225const uCondition = { name: 'Adrian Murray' };
226const uUpdate = { comments: 'None' };
227const update = Telemetry.update(uCondition, uUpdate, uOptions, (err,data)=> {
228    if(err){
229        return errorHandler(err);
230    }
231    // console.log('Document updated');
232});
233
234// Find One and Update
235const findOneAndUpdate = Telemetry.findOneAndUpdate(uCondition, uUpdate,(err,data)=>{
236    if(err){
237        return errorHandler(err);
238    }
239    console.log('Document updated',data);
240});
241
242// Remove
243const date = new Date(2018,12,01);
244const rCondition = { createdOn: { $gte: date }};
245const remove = Telemetry.remove(rCondition, (err) => {
246    if(err){
247        return errorHandler(err);
248    }
249    console.log('Document removed');
250});
251
252// By id and Updte
253const fbidOptions = {
254    new: true, // return the new modified document
255    upsert: false, // create a new doc if not found
256    select: true // specify projection to be returned
257}
258const fbidUpdate = { impediments: 'Blocker' };
259const findByIdAndUpdate = Telemetry.findByIdAndUpdate(id, fbidUpdate, (err, data)=>{
260    if(err){
261        return errorHandler(err);
262    }
263    console.log('findByIdAndUpdate',data);
264});
265
266// By Id and Remove
267const fbirOptions = {
268    select: true // specify projection to be returned
269}        
270const removeCondition = { impediments: 'Blocker' };
271const findByIdAndRemove = Telemetry.findByIdAndRemove(id, removeCondition, fbirOptions, (err, data)=>{
272    if(err){
273        return errorHandler(err);
274    }
275    console.log('findByIdAndRemove',data);
276});
277
278// VALIDATION ============================================================================================
279/* Built-in Validators
280String {required, enum, match}
281Number {required, min, max}
282Date {required}
283Buffer {required}
284Boolean {required}
285Mixed {required}
286ObjectId {required}
287Array {required}
288*/
289
290// Adding validation programatically
291const schema = new Schem({
292    name: { 
293        type: String,
294        required: true
295    },
296    sensor: {
297        type: String
298    }
299});
300schema.path('sensor').required(true, 'You need to add a sensor');
301
302// Built-in Validators
303// Match Validator
304const regex = /[a-zA-Z]/;
305const schema = new Schema ({
306    name: {
307        type: String,
308        required: true,
309        match: regex
310    }
311});
312
313// Enum Validator
314const enum = ['clicks','views','overs'];
315const schema = new Schema({
316    action: {
317        type: String,
318        required: true,
319        enum: enum
320    }
321});
322
323// Min, Max Validator
324const schema = new Schema({
325    amount: {
326        type: Number,
327        min: 1,
328        max: 5
329    }
330});
331
332// Custom validator
333const sizeValidator = [
334    function (val) {
335        return (val.length > 0 && var.length <= 10) ;
336    },
337    'String must be between 1 and 10 characters'
338]
339
340const schema = new Schema({
341   name: {
342       type: String,
343       required: true,
344       validate: sizeValidator
345   }
346})
347
348const Telemetry = new mongoose.model('Telemetry');
349
350const doc = new Telemetry ({name: ''});
351
352doc.save((err) => {
353      return errorHandler(err);
354});
355
356// METHODS ============================================================================================
357/* Model methods
358    find();
359    findById();
360    findOne();
361    where();
362*/
363
364/*
365    Comparison Query Operators
366    $gt
367    $gte
368    $in  exists
369    $lt
370    $lte
371    $ne
372    $nin  does not exist
373*/
374
375/*
376    Update and Remove
377    update();
378    remove();
379    findByIdAndUpdate();
380    findByIdAndRemove();
381*/
382
383

Created on 12/18/2017