Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Aggregate - Query to get items that match key in first item of sort

We have the following records in a collection:

{ "_id" : ObjectId("1"), "date" : ISODate("2017-02-01T00:00:00Z") }
{ "_id" : ObjectId("2"), "date" : ISODate("2017-02-01T00:00:00Z") }
{ "_id" : ObjectId("3"), "date" : ISODate("2017-03-03T00:00:00Z") }
{ "_id" : ObjectId("4"), "date" : ISODate("2017-02-02T00:00:00Z") }
{ "_id" : ObjectId("5"), "date" : ISODate("2017-03-01T00:00:00Z") }
{ "_id" : ObjectId("6"), "date" : ISODate("2017-02-01T00:00:00Z") }
{ "_id" : ObjectId("7"), "date" : ISODate("2017-01-02T00:00:00Z") }
{ "_id" : ObjectId("8"), "date" : ISODate("2017-01-03T00:00:00Z") }

How to filter the most recent records by $month of date field like this:

{ "_id" : ObjectId("3"), "date" : ISODate("2017-03-03T00:00:00Z") }
{ "_id" : ObjectId("5"), "date" : ISODate("2017-03-01T00:00:00Z") }
like image 745
saravana priyan Avatar asked Oct 23 '25 03:10

saravana priyan


2 Answers

  1. $group - Group by the first day of the month year from date and add documents into data array.

  2. $sort - Sort by _id DESC.

  3. $skip

  4. $limit - Take the first document from the result.

  5. $unwind - Deconstruct the data array to multiple documents.

  6. $replaceWith - Replace the document with data document.

db.collection.aggregate([
  {
    $group: {
      _id: {
        "$dateFromParts": {
          "year": {
            $year: "$date"
          },
          "month": {
            $month: "$date"
          },
          "day": 1
        }
      },
      data: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $sort: {
      _id: -1
    }
  },
  {
    $skip: 0
  },
  {
    $limit: 1
  },
  {
    $unwind: "$data"
  },
  {
    $replaceWith: "$data"
  }
])

Sample Mongo Playground

like image 119
Yong Shun Avatar answered Oct 24 '25 18:10

Yong Shun


If you're using collection.find() method, use sort method along with that.
like this : collection.find().sort({created : -1})

If you want to filter, the look at this once :

collection.find({ $expr: {
$eq: [{ $month: "$date" }, 03]
}});

Hope this helps!.

like image 43
sachin Avatar answered Oct 24 '25 16:10

sachin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!