Search code examples
mongodbmongodb-queryaggregation-frameworkmongodb-aggregation

MongoDB get first and last document in aggregate query


How can I get first and last document based on time field. I can use $group and get $first and $last document, but I don't need grouping here, just get first and last full document. Maybe I could use slice? This query doesn't work:

{
  "aggregate": "353469045637980_data",
  "pipeline": [
    {
      "$match": {
        "$and": [
          {
            "time": {
              "$gte": 1461369600
            }
          },
          {
            "time": {
              "$lt": 1461456000
            }
          }
        ]
      }
    },
    {
      "$project": {
        "first": {
          "$slice": 1
        },
        "last": {
          "$slice": -1
        }
      }
    }
  ]
}

Solution

  • Well you need $group but you can simply use a constant (e.g. null, see the docs) for its id so that it results in a single group. $$ROOT then refers to the document itself which you can use with $first and $last like so

    $group: {
      _id: null,
      first: { $first: "$$ROOT" },
      last: { $last: "$$ROOT" }
    }
    

    Of course you can introduce further $project stages to shape that data into an array (as you mentioned you want a list) etc.

    As a side note you may want to introduce a $sort stage to make sure $first and $last have a proper meaning.