1

So I have a code for the aggregation

const documents = await deviceCollection
  .aggregate([
    {
      $match: {
        'readings.t': sensorType,
      },
    },
    { $unwind: '$readings' },
    {
      $project: {
        _id: 0,
        data: ['$readings.r', '$created_at'],
      },
    },
  ])
  .toArray();

return documents.map(({ data }) => data);

and I have a document structure like this one

{
    "readings" : [ 
        {
            "t" : "temperature",
            "r" : 6
        }, 
        {
            "t" : "humidity",
            "r" : 66
        }
    ],
    "created_at" : ISODate("2021-02-24T09:45:09.858Z"),
    "updated_at" : ISODate("2021-02-24T09:45:09.858Z")
}

I need to aggregate r value and created_at as UTC number for a particular reading type in a date range. For example, the expected output for temperature reading is:

[
 [6, 1616061903204],
 [5.6, 1616061903204]
]

But the code returns this

[
    [
        6,
        "2021-02-24T09:45:09.858Z"
    ],
    [
        66,
        "2021-02-24T09:45:09.858Z"
    ],
    [
        5.6,
        "2021-02-24T09:50:09.820Z"
    ],
    [
        68,
        "2021-02-24T09:50:09.820Z"
    ],
]

And it means that I get the humidity type value as well.

1 Answer 1

1
  • $match your condition
  • $unwind deconstruct readings array
  • $match again to filter readings object
  • $toLong to convert ISO date format to timestamp
  • $group by null and construct readings array in a single array
const documents = await deviceCollection.aggregate([
  { $match: { "readings.t": sensorType } },
  { $unwind: "$readings" },
  { $match: { "readings.t": sensorType } },
  {
    $project: {
      readings: [
        "$readings.r",
        { $toLong: "$created_at" }
      ]
    }
  },
  {
    $group: {
      _id: null,
      readings: { $push: "$readings" }
    }
  }
]).toArray();

return documents.length ? documents[0].readings : [];

Playground

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, it works well, but when I add created_at: { $gte: start_date, $lte: end_date }, in the match operator, I receive an empty array for some reason
the data from the request payload ` "date_range": { "start_date": "2021-02-24T09:45:09.858Z", "end_date": "2021-02-24T10:05:09.804Z" }`
you have to convert that date to date type in match created_at: { $gte: new Date(start_date), $lte: new Date(end_date) }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.