Skip to main content

MongoDB Cheatsheet

Feature

  • easy to use, well documented

  • similar to SQL

    • B-Tree
    • ACID Transactions
    • Single Leader Replication
    • Supports $lookup operation, which is basically a left outer join
    • since it's also using B-Tree, indexing is similar to relational SQL
  • Flexible Schema

  • Document Oriented

  • Supports transactions so strong ACID

  • Eventual Consistency

  • Doesn't have global secondary indexes, only Local Indexes

  • Allows cross-shard queries, it will figure out which shard to query and merge the results

What makes MongoDB special compared to RelationalSQL, or other NoSQL databases?

  • Compared to SQL, mongoDB is designed for sharding
  • MongoDB is faster than SQL in terms of read and write, due to flexible schema, efficient data storage, and efficient indexing
  • If given away the benefits of a relational database, then MongoDB is somewhat just as fast as a relational SQL database:
    • only one table, only one index, read and write are more or less the same

Go Driver Referenced From Here

Mongosh

  • use mongosh to interact with mongodb
$ docker exec -it <mongodb_container_id> /bin/bash
# mongosh --username root

Basic CRUD

// show all databases
show dbs

// create or use a database
use blog

// show all collections
db.getCollectionNames()

// Find One
db.users.findOne(filter)
coll.FindOne(ctx, file)

// Find Many
db.users.findMany(filter)
coll.Find(ctx, file)

// Insert One
db.users.insertOne({name:"Logan1"}
coll.InsertOne(ctx, map[string]any{"name": "Logan1"})

// Insert Many
db.users.insertMany([
  {name:"Logan1"},
  {name:"Logan2"}
])

// Update One - $set
db.users.updateOne(
  {name:"Logan1"},
  {$set:{age:101, gender:"M"}}
)
alter table users add age int, gender varchar

// Update Many
db.users.updateMany(
  {age:101},
  {$set:{discount:"Old People Discount"}}
)

// Update one - $unset
db.users.updateOne(
  {name:"Logan1"},
  {$unset:{"age":""}}
)
alter table users drop column age

// Update with $inc:
db.users.updateOne(
  {name: "Logan1"},
  {$inc: {age: 3}},
)
update users set age = age + 3 where name = "Logan1"

// Replace One
db.users.replaceOne(
  {name: 'Logan3'},
  {name: 'Logan3', age: 104}
)

// Upsert (update or insert)
// Available for updateOne, replaceOne, and updateMany
db.users.replaceOne(
  {name: 'Logan3'},
  {$set: {name: 'Logan3', age: 104}},
  {upsert: true}
)

// Delete One
db.users.deleteOne({name: "Logan1"})

// Delete Many
db.users.deleteMany({age: {$gt: 50, $lt:100}})

// Create Index
db.users.createIndex({user_id:1})
create index idx_user_id_asc on user(user_id)

db.users.createIndex({user_id1:1, age:-1})
create index idx_user_id_asc_age_desc on user(userid, age desc)

// Drop collection
db.users.drop()
drop table user

Advance Query

// Filter:
var filter = {name:"Logan2"}
db.users.findOne(filter)
coll.FindOne(ctx, bson.M{"name": "Logan2"}).Decode(&user)

// Query $ne
db.users.find({name: {$ne: "Logan2"}})
coll.Find(ctx, bson.M{"name": bson.M{"$ne": "Logan2"}})
select * from users where name != "Logan2"

// Query $gt, $lt, $gte, $lte
db.users.find({age: {$gt: 25, $lte: 50}})
coll.Find(ctx, bson.M{"age": bson.M{"$gt":25, "$lte":50}})
select * from users where age > 25 and age <= 50

// Query AND
db.users.find({name:"Logan2",age:101})
db.users.find({$and: [{name:"Logan2"},{age:101}]}
coll.Find(ctx, bson.M{"name":"Logan2", "age":101})
select * from users where name = "Logan2" and age = 101

// Query OR
db.users.find({$or: [{name:"Logan1"},{name:"Logan2"}]}
coll.Find(ctx, bson.M{"$or: []bson.M{
  {"name": "Logan1"}, {"name": "Logan2"},
}})
select * from users where name="Logan1" or name="Logan2"

// Query IN
db.users.find({name:{$in:["Logan2", "Logan3"]}})
coll.Find(ctx, bson.M{"name": bson.M{"$in": string[]{"Logan2", "Logan3"}}})
select * from user where name in ("Logan2", "Logan3")

// Query embeded documents
db.inventory.insertMany([
  {item:"Notebook", size:{w:10, h:10, unit:"cm"}},
  {item:"Paer", size:{w:10: h:2, unit:"in"}},
])

  // ** Match one field ** //
db.inventory.find({"size.unit":"cm"})

  // ** Match entir embedded document **//
  // ** Field order matters!! ** //
db.inventory.find({size:{w:10, h:10, unit:"cm"}})

// Query Array
db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] }
]}

  // ** This is like mathcing embedded document ** //
  // ** Needs exact match, including orders ** //
db.inventory.find({tags:["red", "blank"]})

  // ** Find documents that contains all **//
db.inventory.find({tags:{$all:["red", "blank"]}}
coll.Find(ctx, bson.M{"tags": bson.M{"$all": []string{"red", "blank"}}})
select * from users where tags include "red" and tags include "blank"

  // ** Find one match ** //
db.inventory.find({tags: "red"})
select * from users where tags include "red"

  // ** One element can be greater than 15, and another be less than 20 ** //
db.inventory.find({dim_cm:{$gt:15, $lt: 20}})

  // ** Use $elemMatch to specify multiple criteria on the same elment
db.inventory.find({dim_cm: {$elemMatch: {$gt:15, $lt: 20}}})
coll.Find(ctx, bson.M{
  "dim_cm": bson.M{
    "$elemMatch": bson.M{
      "$gt":15, "$lt":20,
    },
  },
}

  // ** Specify index of element, first element by grearter than 25 ** //
db.inventory.find({"dim_cm.0": {$gt:25}})

  // ** Specify size of array ** //
db.inventory.find({tags: {$size: 3}})

// Contains one of ["123", "321", "456", "654"]
db.users.find({members: {$elemMatch: {uuid: {$in: ["123", "321", "456", "654"]}}}})
coll.Find(ctx, bson.M{
  "members": bson.M{
    "$elemMatch": bson.M{
      "uuid": bson.M{
        "$in": []string{"123", "321", "456", "654"},
      },
    },
  },
})

// Contains all of ["123", "321", "456", "654"]
db.users.find({members: {$all: [
  {$elemMatch: {"uuid", "123"}},
  {$elemMatch: {"uuid", "321"}},
  {$elemMatch: {"uuid", "456"}},
  {$elemMatch: {"uuid", "654"}}
]}})
coll.Find(ctx, bson.M{
	"is_group_chat": false,
	"members": bson.M{"$all": []bson.M{
		{"$elemMatch": bson.M{"uuid": userUUID1}},
		{"$elemMatch": bson.M{"uuid": userUUID2}},
	}},
})

// Sort
db.users.find().sort({user_id: 1})
select * from users order by user_id asc

db.users.find().sort({user_id: -1})
select * from users order by user_id desc

// Count
db.users.count()
db.users.find().count()
select count(*) from users

db.users.count({user_id: {$exists: true}})
select count(user_id) from users

db.users.count({age: {$gt: 30}})
select count(*) from users where age > 30

db.users.aggregate([{$group: {_id: "$status"}}])
select distinct(status) from users

// Limit
db.users.find().limit(5).skip(10)
select * from people limit 5 skip 10

// Explain
db.users.find({status: "A"}).explain()
explain select * from users where status = "A"

// Select target fields:
db.inventory.find({status:"A"}, {item:1, status:1})
SELECT _id, item, status from inventory WHERE status = "A"

db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
SELECT item, status from inventory WHERE status = "A"

db.inventory.find( { status: "A" }, { status: 0, instock: 0 } )
// Returns all fields except for status and instock

// Select target fields in embedded documents:
db.inventory.find(
   { status: "A" },
   { item: 1, status: 1, "size.uom": 1 }
)

// Select last element from the instock array with $slice
db.inventory.find(
  { status: "A" },
  { item: 1, status: 1, instock: { $slice: -1 }}
)

// Aggregation:
db.inventory.find(
   { },
   {
      _id: 0,
      item: 1,
      status: {
         $switch: {
            branches: [
               {
                  case: { $eq: [ "$status", "A" ] },
                  then: "Available"
               },
               {
                  case: { $eq: [ "$status", "D" ] },
                  then: "Discontinued"
               },
            ],
            default: "No status found"
         }
      },
      area: {
         $concat: [
            { $toString: { $multiply: [ "$size.h", "$size.w" ] } },
            " ",
            "$size.uom"
         ]
      },
      reportNumber: { $literal: 1 }
   }
)

// OUTPUT:
[
   {
      item: 'journal',
      status: 'Available',
      area: '294 cm',
      reportNumber: 1
   },
   {
      item: 'planner',
      status: 'Discontinued',
      area: '685.5 cm',
      reportNumber: 1
   },
   {
      item: 'notebook',
      status: 'Available',
      area: '93.5 in',
      reportNumber: 1
   }
]







Regex

// Query Regex
db.users.find({name: {$regex: /o/}})
db.users.find({name: /o/})
select * from users where name like '%o%'

// Begin with
db.users.find({name: /^log/})
select * from users where name like 'log%'








Other functions

// $mul => multiply the price of item by 1.5
db.inventory.updateOne({sku:"abc123"}, {$mul: {price: 1.5}})
coll.UpdateOne(ctx, bson.M{"sku":"abc123"}, bson.M{"$mul": bson.M{"price": 1.5}})