MongoDB C# docs
GitHub.NET DriverMongoDB docs
  • ⭐Introduction
  • πŸ“ŒGetting started
    • Environment setup
    • πŸƒβ€β™‚οΈ Quick start
      • MongoDB connection
      • Databases
      • Collections
      • Insert documents
      • Read documents
      • Update documents
  • πŸ“‘CRUD Basics
    • βž•Create
      • Id Member
      • Ordered insert
    • πŸ”ŽRead
      • Basics
      • Comparison Operators
      • Logical Operators
      • Element Operators
      • Array operators
      • Evaluation Operators
    • πŸ“Update
      • Operators
      • Replace
      • Arrays
    • ❌Delete
  • πŸ§ͺAggregation
    • Overview
    • βœ‚οΈProject
    • 🎯Match
    • πŸ“¦Group
    • 🚩Unwind
    • ⏩Pagination
    • πŸ“ˆBucket
    • ✨Operators
Powered by GitBook
On this page
  1. Aggregation

Unwind

PreviousGroupNextPagination

Last updated 5 years ago

Array deconstruction

The $unwind operator is used to deconstruct array fields. How deconstruction works For each array element a new document is produced having that element in the position of the field array. This means that applying the unwind operator on a single document's array field which contains 10 elements, produces 10 different documents having one of the array elements instead of the array field. It is possible to define if a new document will produced in case a document either doesn't contain the array field or it is empty.

{
	"_id" : ObjectId("5e9afcd20f86e454c4518d8d"),
	"name" : "Margarett Lind",
	"age" : 59,
	"activities" : [
		"Golf",
		"Photography",
		"Hacking"
	]
}
// $unwind on activities
db.trips.aggregate()
    .unwind("$activities")

// for each activity produces one document

/* 1 */
{
	"_id" : ObjectId("5e9afcd20f86e454c4518d8d"),
	"name" : "Margarett Lind",
	"age" : 59,
	"activities" : "Golf"
	
},

/* 2 */
{
	"_id" : ObjectId("5e9afcd20f86e454c4518d8d"),
	"name" : "Margarett Lind",
	"age" : 59,
	"activities" : "Photography"
},

/* 3 */
{
	"_id" : ObjectId("5e9afcd20f86e454c4518d8d"),
	"name" : "Margarett Lind",
	"age" : 59,
	"activities" : "Hacking"
}

The following sample finds the distinct activities grouped by age for Traveler documents.

Unwind.cs
var travelersQueryableCollection = tripsDatabase
    .GetCollection<Traveler>(Constants.TravelersCollection)
    .AsQueryable();

var linqQuery = travelersQueryableCollection
    .SelectMany(t => t.Activities, (t, a) => new
    {
        age = t.Age,
        activity = a
    })
    .GroupBy(q => q.age)
    .Select(g => new { age = g.Key, activities = 
        g.Select(a => a.activity).Distinct() })
    .OrderBy(r => r.age);

var linqQueryResults = await linqQuery.ToListAsync();
db.travelers.aggregate([
   {
      "$unwind":"$activities"
   },
   {
      "$project":{
         "age":"$age",
         "activity":"$activities",
         "_id":0
      }
   },
   {
      "$group":{
         "_id":"$age",
         "__agg0":{
            "$addToSet":"$activity"
         }
      }
   },
   {
      "$project":{
         "age":"$_id",
         "activities":"$__agg0",
         "_id":0
      }
   },
   {
      "$sort":{
         "age":1
      }
   }
])
// sample results

/* 1 */
{
	"age" : 22,
	"activities" : [
		"Photography",
		"Road Touring"
	]
},

/* 2 */
{
	"age" : 25,
	"activities" : [
		"Photography",
		"Blogging",
		"Baking",
		"Collecting",
		"Hacking"
	]
},

/* 3 */
{
	"age" : 30,
	"activities" : [
		"Road Touring",
		"Climbing"
	]
},

/* 4 */
{
	"age" : 34,
	"activities" : [
		"Photography"
	]
}
public class Traveler
{
    [BsonId]
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public List<string> Activities { get; set; }
    public List<VisitedCountry> VisitedCountries { get; set; }
}

LINQ query explanation

  • SelectMany on Activities creates the $unwind stage

  • new { } creates the $project stage

  • GroupBy groups documents by age field

  • Selectcreates another $project stage where Distinct ensures activities will not contain duplicate values per group - it does that by using $addToSet operator in the $group stage rather than a $push

πŸ§ͺ
🚩
❓