Cara menggunakan create array mongodb aggregation

MongoDB $unwind is a useful tool in performing aggregation in MongoDB. Let’s take a look at $unwind and how to use it.

(This article is part of our MongoDB Guide. Use the right-hand menu to navigate.)

What is MongoDB $unwind?

The MongoDB $unwind operator is used to deconstruct an array field in a document and create separate output documents for each item in the array.

The only difference between the input document and output documents is that, in output documents, the value of the array field is replaced by a single item from the input document array. You will see this as I walk you through this example.

MongoDB $unwind transforms complex documents into simpler documents, which increase readability and understanding. This also allows us to perform additional operations, like grouping and sorting on the resulting output.

The basic syntax of $unwind operator

{ $unwind: "$<field path/ array path>" }
{$unwind: { path : "$<field path/ array path>", <optional arguments>}}

Here, you should prefix the path with the dollar sign “$” for a successful $unwind operation.

Next, we will demonstrate a simple $unwind operation using our “vehicledetails” collection. First, let’s have a look at our collection.

db.vehicledetails.find().pretty()

Result:

Cara menggunakan create array mongodb aggregation

Next, we use the $unwind operator to deconstruct the “model_year” array field and to create separate documents for each year.

db.vehicledetails.aggregate([{$unwind : "$model_year" }]).pretty()

Result:

Cara menggunakan create array mongodb aggregation

As shown in the above output, a new document is created for each item in the “model_year” array.

How $unwind works with non-array field paths

Before MongoDB 3.2, if a non-array field is defined as the path in the $unwind operator, it would have resulted in an error. From MongoDB 3.2 onwards, any non-array field which does not resolve to a missing, null, or empty array will be treated as a single element array.

This next example shows how the $unwind operator handles a single element array.

db.vehicledetails.aggregate([{$unwind : "$make" }]).pretty()

Result:

Cara menggunakan create array mongodb aggregation

Here, the $unwind operation successfully creates a single output document as it considers the “make” field as a single item array.

Missing field as the path

The $unwind operator will not generate any output if the specified path is a missing/unavailable field. There will be no error as the $unwind will ignore the input document.

db.vehicledetails.aggregate([{$unwind : "$use" }]).pretty()

Result:

Cara menggunakan create array mongodb aggregation

In the above operation, the provided path for the $unwind operator is the “use” field. However, the input document is ignored, as there is no “use” field in the input document.

$unwind operator options

The $unwind operator can be used with two optional arguments, which are includeArrayIndex and preserveNullAndEmptyArrays. This section will demonstrate how each option affects the result of an $unwind operation.

Again, we’ll use the “vehicledetails” collection with additional documents to demonstrate the functionality of the optional arguments.

db.vehicledetails.find().pretty()

Result:

Cara menggunakan create array mongodb aggregation

When you perform $unwind operation on the above data set with the “model_year” field, the output will consist of five results.

Let’s see this in this example:

db.vehicledetails.aggregate([{$unwind : "$model_year" }]).pretty()

Result:

Cara menggunakan create array mongodb aggregation

includeArrayIndex option

The includeArrayIndex option is used to obtain the array index with the $unwind operation output. We can define a field in the “includeArrayIndex” syntax to get the array index of each output document. If the array field is null, this will result in a null value in the user-defined field, and if an empty array is present, it will be ignored as there are no items in that array.

In the below example, the “model_year” field is used to carry out the $unwind operation, and the user-defined “vehicleIndex” field is used to capture the array index.

db.vehicledetails.aggregate([{$unwind : {path: "$model_year", includeArrayIndex: "vehicleIndex" }}]).pretty()

Result:

Cara menggunakan create array mongodb aggregation

preserveNullAndEmptyArrays option

Defining the “preserveNullAndEmptyArrays” option in a $unwind operation allows the user to include documents where the array field is missing, null, or an empty array. The “preserveNullAndEmptyArrays” option only takes Boolean arguments like true or false.

Let’s use the documents within the “vehicledetails” collection to demonstrate “preserveNullAndEmptyArrays” option. This will result in an output where all missing, null, or empty arrays in the “model_year” field are captured.

db.vehicledetails.aggregate([{$unwind : {path: "$model_year", preserveNullAndEmptyArrays: true}}]).pretty()

Result:

Cara menggunakan create array mongodb aggregation

Grouping data by Unwound values

In MongoDB, you can use the resulting dataset of a $unwind operation—unwound values—to further transform the data set.

The “vehiclesalesmain” collection is used to demonstrate how to combine $unwind operator with other functions.

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
0

Result:

Cara menggunakan create array mongodb aggregation

In the next section, the “colours” array is used to perform the $unwind operation. We also use MongoDB group and sort methods to get the average price according to the vehicle colours.

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
1

Result:

Cara menggunakan create array mongodb aggregation

Let’s simplify the above formula in several steps to get a better understanding of the process. You can see the complete formatted syntax below.

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
2

Step 1

In the first step, the documents in the “vehiclesalesmain” collection are unwound using the “colours” array field. Then the preserveNullAndEmptyArrays is set to true to capture any missing, null, or empty arrays in the resulting output.

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
3

Result:

Cara menggunakan create array mongodb aggregation

Step 2

In the second step, documents resulting from the $unwind operation are grouped by the MongoDB group method using the colour, and the average price for each colour is calculated.

Grouping syntax:

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
4

Complete syntax:

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
5

Result:

Cara menggunakan create array mongodb aggregation

Step 3

Finally, the grouped data set is sorted in descending order using the MongoDB sort method.

Sorting syntax:

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
6

Complete syntax:

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
1

Result:

Cara menggunakan create array mongodb aggregation

Using $unwind on embedded arrays

When you perform the $unwind operation on an embedded array, it will function the same way as on a normal array field. The $unwind operation will deconstruct the items in each of the embedded arrays.

Using the “vehicleitems” collection, we will demonstrate how the $unwind operator functions on an embedded array. Let’s have a look at the “vehicleitems” collection.

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
8

Result:

Cara menggunakan create array mongodb aggregation

In the next section, the $unwind operation is performed on the above documents using the “items” embedded arrays.

{$unwind: { path : "$<field path/ array path>", <optional arguments>}}
9

Result:

Cara menggunakan create array mongodb aggregation

As you can see from the output documents, each item in all the “items” embedded arrays are deconstructed as individual items. You can further deconstruct the resulting data set using the “type” array, which we do in the next example.