Home > Net >  MongoDB: Include fields during grouping in addition to accumulator
MongoDB: Include fields during grouping in addition to accumulator

Time:12-29

In the collection, I have entries as such:

{
  _id: new ObjectId("61cae11f8fc0b2e3b045be04"),
  location: 'Station One',
  datetime: 2019-02-02T12:54:57.937Z,
  sensorType: 'temperature',
  value: -1.8,
  __v: 0
},
{
  _id: new ObjectId("61cae11f8fc0b2e3b045be05"),
  location: 'Station two',
  datetime: 2019-02-02T09:49:39.200Z,
  sensorType: 'temperature',
  value: -2,
  __v: 0
},

When I make an aggregate query, I match for certain things, such as what dates to include etc, and then in the grouping, I want to search for the minimum and maximum temperature of that station during the matched time period. I have the following grouping section

let group = {
    _id: {location: '$location'},
    max: { $max: '$value' },
    min: { $min: '$value' },
}

This gives me the correct result like so:

[
  {
    _id: { location: "Station One" },
    max: 2.3,
    min: -22.4
  },
  {
    _id: { location: 'Station Two' },
    max: 9.8,
    min: -9.8
  }
]

What I want to do is add a datetime for that specific temperature was recorded like so:

[
  {
    _id: { location: "Station One" },
    max: 2.3, **DATETIME HERE**
    min: -22.4 **DATETIME HERE**
  },
  {
    _id: { location: 'Station Two' },
    max: 9.8, **DATETIME HERE**
    min: -9.8 **DATETIME HERE**
  }
]

I am very new to mongo and I tried all sorts of things without success, for example:

let group = {
    _id: {location: '$location'},
    max: { $max: '$value', $first: '$datetime' },
    min: { $min: '$value' },
}

this try gives me an error that max must have one accumulator.

How can I add datetime to min and max values?

CodePudding user response:

Credit to @Prasad_'s recommendation, the aggregation pipeline can be simplified as:

  1. $sort - Sort by location and value ascending.
  2. $group - Group by location. Use $first to get the document with min value. $last to get the document with max value.
  3. $project - Decorate output document.
db.collection.aggregate([
  {
    $sort: {
      location: 1,
      value: 1
    }
  },
  {
    $group: {
      _id: {
        location: "$location"
      },
      min: {
        $first: "$$ROOT"
      },
      max: {
        $last: "$$ROOT"
      }
    }
  },
  {
    $project: {
      _id: 1,
      max: {
        value: "$max.value",
        datetime: "$max.datetime"
      },
      min: {
        value: "$min.value",
        datetime: "$min.datetime"
      }
    }
  }
])

Sample Mongo Playground

  • Related