Skip to content
Zhengyuan Zhu
Go back

MongoDB Advanced Design Patterns

After using mongodb for such a long time, I seem to have hit a bottleneck. This article revisits mongo through several blog posts, hoping to gain new insights. Review the old to learn the new~

Main Understanding of MongoDB:

Differences Between Traditional Relational Model (SQL) and Document Model

Advantages of Document Model

Basic Strategies for MongoDB Document Schema Design

Prefer Embedding, Then Consider Referencing

MongoDB Design Pattern Principles

Classic Design Pattern Cases

E-Commerce

Design Considerations

Reference Data Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    "_id": ObjectId("*")
    "userid": 1234,
    "last_activity": ISODate(...), // Use TTL to automatically delete unpaid shopping carts
    "status": "active",
    "items":[
        {
            "itemid": 1234,
            "title": "Milk",
            "price": 5.00,
            "quantity": 1,
            "img_url": "milk,jpg"
        },
        {
            "itemid": 4567,
            "title": "Eggs",
            "price": 3.00,
            "quantity": 1,
            "img_url": "eggs.jpg"
        }
    ]
}

Operations on the Model

Add item to shopping cart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
db.cart.update({
    "_id": ObjectId("*")
}, {
    $push:{
        "items":{
            "itemid": 2345,
            "title": "Bread",
            "price": 2.00,
            "quantity": 1,
            "img_url": "bread.jpg"
        }
    },
    $set:{
        "last_activity": ISODate()
    }
})

Update quantity of a certain item

1
2
3
4
5
6
7
8
9
10
db.carts.update({
    "id": ObjectId("*")
    "items.itemid": 4567
},{
    $set:{
        "item.$.quantity": 5,
        "last_activity": ISODate()
    }
}
)

Count total quantity of items (aggregation operation)

1
2
3
4
5
6
7
8
9
10
db.cart.createIndex({"items.itemid": 1})
db.cart.aggregate(
    { $match: {"items.itemid": 8910}}, # Filter out items with id 8910 in shopping cart
    { $unwind: "$items" }, # Expand items array, each array element becomes a document
    { $group: {
        "_id": "$items.itemid",
        "amount": { "$sum" : "$items.quantity" }
        }
    }#Use aggregation operation $sum to sum the quantity of each item
)

Social

Design Considerations

Problems with Classic Document Design

1
2
3
4
5
6
{
    "id": "Yuan",
    "fullname": "Zhu Zheng Yuan",
    "followers": ["Oscar", "Mandy"],
    "following": ["Mandy", "Bert"]
}

 If TJ is a celebrity, those who follow me might be in the tens of millions. An array of tens of millions will have two problems:

  1. It may exceed the hard limit of a document maximum 16M; 2. MongoDB arrays that are too large will seriously affect performance.  The solution is to create a dedicated collection to describe following relationships.
1
2
3
4
5
> db.follower.find()
{"_id": ObjectId(), "user": "Yuan", "following": "Mandy"}
{"_id": ObjectId(), "user": "Yuan", "following": "Bert"}
{"_id": ObjectId(), "user": "Oscar", "following" : "Yuan"}
{"_id": ObjectId(), "user": "Mandy", "following": "Yuan"}

News Feed Implementation

News feed: List displaying latest status of all followed users

Solutions:

References:


Share this post on:

Previous Post
GRE Reading Introduction
Next Post
Gradient Descent in Machine Learning
Jack the orange tabby cat
I'm Jack 🧡
Luna the tuxedo cat
I'm Luna! 🖤