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
  • Slice operator - $slice
  • Get first N elements
  • Get last N elements
  • Pagination
  • Filter operator - $filter
  • Multiply operator - $multiply
  1. Aggregation

Operators

Slice operator - $slice

The $slice operator is used to return a subset of an array. The Enumerable.Take method can be used to create a $slice operation on a array field.

Method call

Description

Take(1)

Returns the first element

Take(N)

Returns the first N elements

Take(-1)

Returns the last element

Take(-N)

Returns the last N elements

Get first N elements

The sample returns Traveler documents but only include the first element of their VisitedCountries array field.

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

var sliceQuery = from t in travelersQueryableCollection
    select new {
        t.Name, visitedCountries = 
        t.VisitedCountries.Take(1) // slice here
    };

var sliceQueryResults = await sliceQuery.ToListAsync();
db.travelers.aggregate()
.project(
    {   
        name: 1, 
        visitedCountries : { 
            $slice: ["$visitedCountries", 1] 
        }
    })

-------------------

// sample result
{
	"_id" : ObjectId("5e9d705b45359358b426065f"),
	"name" : "Leopoldo Lueilwitz",
	"visitedCountries" : [ // only one item
		{
			"name" : "Malta",
			"timesVisited" : 9,
			"lastDateVisited" : ISODate("2017-12-19T21:22:35.607+02:00"),
			"coordinates" : {
				"latitude" : 79.2858,
				"longitude" : 13.7049
			}
		}
	]
}
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; }
}

The same result can be achieved using a ProjectionDefinition.

var sliceProjection = Builders<Traveler>.Projection
    .Expression(u =>
    new
    {
        name = u.Name,
        visitedCountries = u.VisitedCountries.Take(1)
    });

var sliceProjectionResults = await travelersCollection
    .Find(Builders<Traveler>.Filter.Empty)
    .Project(sliceProjection)
    .ToListAsync();

Get last N elements

The following sample returns the Traveler documents but only the last 2 visited countries included.

Slice.cs
var sliceQueryTwoLastCountries = 
   from t in travelersQueryableCollection
   select new 
   { 
      t.Name, 
      visitedCountries = t.VisitedCountries.Take(-2) 
   };

var sliceQueryTwoLastCountriesResults = 
   await sliceQueryTwoLastCountries
   .ToListAsync();
db.travelers
  .aggregate()
  .project(
  { 
    name: 1, 
    visitedCountries : 
        { $slice: ["$visitedCountries", -2] } 
  })
  
-----------------------

// sample result

{
	"_id" : ObjectId("5e9d96f37db33d7ec8aed9ee"),
	"name" : "Emmitt Wuckert",
	"visitedCountries" : [ // last two
		{
			"name" : "Greece",
			"timesVisited" : 1,
			"lastDateVisited" : ISODate("2019-05-30T15:26:04.146+03:00"),
			"coordinates" : {
				"latitude" : 23.1572,
				"longitude" : 36.6096
			}
		},
		{
			"name" : "Malta",
			"timesVisited" : 5,
			"lastDateVisited" : ISODate("2017-12-08T05:52:58.182+02:00"),
			"coordinates" : {
				"latitude" : -75.3477,
				"longitude" : 97.188
			}
		}
	]
}
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; }
}

Pagination

Slice can be combined with the Skip method and provide full pagination functionality. The following sample skips the first 2 VisitedCountries array elements and returns the next 3.

var travelersQueryableCollection = tripsDatabase
    .GetCollection<Traveler>(Constants.TravelersCollection)
    .AsQueryable();
    
var sliceWithSkipQuery = 
    from t in travelersQueryableCollection
    select new { 
        t.Name, 
        visitedCountries = t.VisitedCountries
                            .Skip(2).Take(3) };

var sliceWithSkipQueryResults = 
    await sliceQuery.ToListAsync();
db.travelers.aggregate([
   {
      "$project":{
         "Name":"$name",
         "visitedCountries":{
            "$slice":[
               "$visitedCountries", 2, 3
            ]
         },
         "_id":0
      }
   }
])

-----------------------------
// sample result

{
	"Name" : "Kristofer Gutkowski",
	"visitedCountries" : [
		{ // 3rd
			"name" : "Austria",
			"timesVisited" : 1,
			"lastDateVisited" : ISODate("2016-05-22T17:30:10.643+03:00"),
			"coordinates" : {
				"latitude" : -25.3767,
				"longitude" : -114.1358
			}
		},
		{ // 4th
			"name" : "Tokelau",
			"timesVisited" : 5,
			"lastDateVisited" : ISODate("2019-02-15T16:33:06.861+02:00"),
			"coordinates" : {
				"latitude" : -83.42,
				"longitude" : 65.0535
			}
		},
		{ // 5th
			"name" : "Libyan Arab Jamahiriya",
			"timesVisited" : 2,
			"lastDateVisited" : ISODate("2015-08-31T14:34:19.979+03:00"),
			"coordinates" : {
				"latitude" : -65.3698,
				"longitude" : -93.8438
			}
		}
	]
}
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; }
}

Filter operator - $filter

The $filter operator is used to match and return array elements that fulfill the specified condition. The Enumerable.Where method can be used to create the condition.

The sample returns Traveler documents with their VisitedCountries array field containing only the countries that have been visited once.

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

var filterQuery = 
    from t in travelersQueryableCollection
    select new
    {
         t.Name,
         visitedCountries = t.VisitedCountries
                 .Where(c => c.TimesVisited == 1)
    };

var filterQueryResults = await filterQuery.ToListAsync();
db.travelers.aggregate([
   {
      "$project":{
         "name":"$name",
         "visitedCountries":{
            "$filter":{
               "input":"$visitedCountries",
               "as":"c",
               "cond":{
                  "$eq":[
                     "$$c.timesVisited",
                     1
                  ]
               }
            }
         },
         "_id":0
      }
   }
])

------------------------------

// sample result

/* 1 */
{
	"name" : "Emmitt Wuckert",
	"visitedCountries" : [
		{
			"name" : "Djibouti",
			"timesVisited" : 1, // matched
			"lastDateVisited" : ISODate("2019-03-10T04:36:32.678+02:00"),
			"coordinates" : {
				"latitude" : -45.7154,
				"longitude" : 60.261
			}
		},
		{
			"name" : "Greece",
			"timesVisited" : 1, // matched
			"lastDateVisited" : ISODate("2019-05-30T15:26:04.146+03:00"),
			"coordinates" : {
				"latitude" : 23.1572,
				"longitude" : 36.6096
			}
		}
	]
}
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; }
}

Multiply operator - $multiply

The $multiply operator is used to multiply numbers and return the result. The operator can be used with both raw and field values.

Assuming a collection contains Order documents in the following format...

{
    "_id" : 0,
    "item" : "Handmade Steel Shoes",
    "price" : 172,
    "quantity" : 3,
    "shipmentDetails" : {
        "shipAddress" : "547 Kris Hill, Dooleyville, Niger",
        "city" : "Port Caryport",
        "country" : "Northern Mariana Islands",
        "contactName" : "Keenan McDermott",
        "contactPhone" : "1-956-915-2404"
    }
}

The sample creates a projection stage to return the total for each order, with total=priceβˆ—quantitytotal = price * quantitytotal=priceβˆ—quantity

Multiply.cs
var ordersCollection = tripsDatabase
    .GetCollection<Order>(Constants.OrdersCollection);

var multiplyQuery = 
    from o in ordersCollection.AsQueryable()
    select new // creates a projection stage
    {
      o.OrderId,
      total = o.Quantity * o.Price // $multiply field
    };

var multiplyQueryResults = 
    await multiplyQuery.ToListAsync();
db.orders.aggregate([
  {
    $project: {
      OrderId: '$_id',
      total: { $multiply: ['$quantity', '$price'] },
      _id: 0
    }
  }
]);

----------------------------

// sample results

{ "OrderId" : 0, "total" : 516 }
{ "OrderId" : 1, "total" : 450 }
{ "OrderId" : 2, "total" : 752 }
{ "OrderId" : 3, "total" : 1848 }
{ "OrderId" : 4, "total" : 870 }
{ "OrderId" : 5, "total" : 544 }
{ "OrderId" : 6, "total" : 752 }
public class Order
{
    [BsonId]
    public int OrderId { get; set; }
    public string Item { get; set; }
    public  int Price { get; set; }
    public int Quantity { get; set; }

    [BsonIgnoreIfDefault]
    public int? LotNumber { get; set; }

    public ShipmentDetails ShipmentDetails { get; set; }
}
PreviousBucket

Last updated 5 years ago

πŸ§ͺ
✨