0
0
MongodbHow-ToBeginner · 2 min read

MongoDB Query to Calculate Percentage of a Field

Use MongoDB's aggregation framework with $group to sum values and then $project to calculate percentage like { $multiply: [{ $divide: ["$value", "$total"] }, 100] }.
📋

Examples

InputDocuments: [{ category: 'A', value: 30 }, { category: 'B', value: 70 }]
Output[{ category: 'A', percentage: 30 }, { category: 'B', percentage: 70 }]
InputDocuments: [{ category: 'X', value: 50 }, { category: 'Y', value: 50 }]
Output[{ category: 'X', percentage: 50 }, { category: 'Y', percentage: 50 }]
InputDocuments: [{ category: 'Z', value: 0 }]
Output[{ category: 'Z', percentage: 0 }]
🧠

How to Think About It

First, sum all values to get the total. Then, for each document, divide its value by the total and multiply by 100 to get the percentage. Use $group to sum and $project to calculate percentages.
📐

Algorithm

1
Group all documents to calculate the total sum of the target field.
2
Join the total sum back to each document.
3
Calculate the percentage by dividing each document's value by the total sum and multiply by 100.
4
Project the desired fields including the calculated percentage.
💻

Code

mongodb
db.collection.aggregate([
  { $group: { _id: null, total: { $sum: "$value" } } },
  { $lookup: {
      from: "collection",
      pipeline: [],
      as: "docs"
    }
  },
  { $unwind: "$docs" },
  { $project: {
      category: "$docs.category",
      percentage: { $multiply: [ { $divide: ["$docs.value", "$total"] }, 100 ] }
    }
  }
])
Output
[ { "category" : "A", "percentage" : 30 }, { "category" : "B", "percentage" : 70 } ]
🔍

Dry Run

Let's trace the example with documents [{category: 'A', value: 30}, {category: 'B', value: 70}] through the aggregation.

1

Calculate total sum

Sum values: 30 + 70 = 100

2

Join total to each document

Each document now has total = 100

3

Calculate percentage

For 'A': (30 / 100) * 100 = 30%, for 'B': (70 / 100) * 100 = 70%

categoryvaluetotalpercentage
A3010030
B7010070
💡

Why This Works

Step 1: Summing values

The $group stage adds all value fields to get the total sum.

Step 2: Joining total to documents

Using $lookup and $unwind, the total sum is attached to each document for calculation.

Step 3: Calculating percentage

The $project stage divides each document's value by the total and multiplies by 100 to get the percentage.

🔄

Alternative Approaches

Using $facet to calculate total and percentages in one pipeline
mongodb
db.collection.aggregate([
  { $facet: {
      total: [ { $group: { _id: null, total: { $sum: "$value" } } } ],
      data: [ { $project: { category: 1, value: 1 } } ]
    }
  },
  { $unwind: "$total" },
  { $unwind: "$data" },
  { $project: {
      category: "$data.category",
      percentage: { $multiply: [ { $divide: ["$data.value", "$total.total"] }, 100 ] }
    }
  }
])
This method calculates total and data in parallel but can be more complex to read.
Calculate percentage client-side after fetching total
mongodb
// Fetch total sum first
const total = db.collection.aggregate([{ $group: { _id: null, total: { $sum: "$value" } } }]).toArray()[0].total;
// Then fetch documents and calculate percentage in application code
Simpler aggregation but requires two queries and client-side calculation.

Complexity: O(n) time, O(n) space

Time Complexity

The aggregation scans all documents once to sum values and then processes each document to calculate percentages, resulting in O(n) time.

Space Complexity

Extra space is used to hold the aggregation pipeline state and output, proportional to the number of documents, so O(n).

Which Approach is Fastest?

Calculating total and percentages in one pipeline is efficient; client-side calculation requires multiple queries and more network overhead.

ApproachTimeSpaceBest For
Single aggregation pipelineO(n)O(n)All-in-one server-side calculation
$facet methodO(n)O(n)Parallel calculation but more complex
Client-side calculationO(n) + networkO(n)Simple aggregation but requires multiple queries
💡
Always calculate the total sum first before computing percentages in MongoDB aggregation.
⚠️
Forgetting to multiply by 100 after dividing to get the percentage value.