0
0
MongodbHow-ToBeginner · 2 min read

MongoDB Query to Flatten Array Using $unwind

Use the MongoDB aggregation pipeline stage $unwind to flatten an array field into multiple documents, like { $unwind: "$arrayField" }.
📋

Examples

Input{ _id: 1, items: ["apple", "banana"] }
Output{ _id: 1, items: "apple" } { _id: 1, items: "banana" }
Input{ _id: 2, tags: ["red", "blue", "green"] }
Output{ _id: 2, tags: "red" } { _id: 2, tags: "blue" } { _id: 2, tags: "green" }
Input{ _id: 3, values: [] }
Output
🧠

How to Think About It

To flatten an array in MongoDB, think of splitting each array element into its own document. The $unwind operator does this by taking each element of the array and creating a separate output document for it, effectively 'flattening' the array.
📐

Algorithm

1
Start with the collection containing documents with array fields.
2
Apply the aggregation pipeline with the <code>$unwind</code> stage on the target array field.
3
Each array element becomes a separate document with the same other fields.
4
Collect the output documents as the flattened result.
💻

Code

mongodb
db.collection.aggregate([
  { $unwind: "$items" }
])
Output
{ "_id" : 1, "items" : "apple" } { "_id" : 1, "items" : "banana" }
🔍

Dry Run

Let's trace flattening the array ["apple", "banana"] in the document { _id: 1, items: ["apple", "banana"] }.

1

Input Document

{ _id: 1, items: ["apple", "banana"] }

2

Apply $unwind

Split array into two documents: { _id: 1, items: "apple" } and { _id: 1, items: "banana" }

_iditems
1apple
1banana
💡

Why This Works

Step 1: What $unwind Does

$unwind takes an array field and outputs one document per array element.

Step 2: Preserving Other Fields

All other fields in the document stay the same for each output document.

Step 3: Resulting Documents

The result is a set of documents each with a single array element, effectively flattening the array.

🔄

Alternative Approaches

Using $project with $reduce and $concatArrays
mongodb
db.collection.aggregate([
  { $project: {
      flattened: { $reduce: {
        input: "$arrayField",
        initialValue: [],
        in: { $concatArrays: ["$$value", ["$$this"]] }
      }}
    }}
])
This method creates a new flattened array but does not split documents; useful for nested arrays.
Using $unwind with preserveNullAndEmptyArrays
mongodb
db.collection.aggregate([
  { $unwind: { path: "$arrayField", preserveNullAndEmptyArrays: true } }
])
Keeps documents with empty or missing arrays instead of dropping them.

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

Time Complexity

The operation processes each element in the array once, so time grows linearly with the total number of array elements.

Space Complexity

Output documents increase with the number of array elements, so space usage is proportional to the flattened size.

Which Approach is Fastest?

$unwind is the most efficient for flattening arrays into separate documents; alternatives may be slower or more complex.

ApproachTimeSpaceBest For
$unwindO(n)O(n)Splitting array elements into separate documents
$project with $reduceO(n)O(n)Flattening nested arrays into a single array
$unwind with preserveNullAndEmptyArraysO(n)O(n)Flattening while keeping empty or missing arrays
💡
Use $unwind to flatten arrays quickly in aggregation pipelines.
⚠️
Forgetting to use $unwind and trying to flatten arrays with simple find queries.