Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Formatting dates with $dateToString in nested arrays

I have a collection of documents where each document represents a location of charging stations. I’m trying to use $map and $dateToString to transform each last_updated field into a string and drop the milliseconds portion of the datetime. There can be up to 3 last_updated fields on a location. A top level last_updated, a last_updated for each evse within an evses array, and a last_updated field within each connector of each evse. It is also possible for the evses array to not be present.

Here is an example of 2 locations:

[
    {
        "id" : "A",
        "name" : "Meades Park",
        "evses" : [
            {
                "uid" : "B",
                "connectors" : [
                    {
                        "id" : "C",
                        "standard" : "IEC_62196_T1",
                        "last_updated" : ISODate("2021-02-18T23:54:56.000Z")
                    }
                ],
                "last_updated" : ISODate("2021-02-18T23:54:56.000Z")
            },
            {
                "uid" : "D",
                "connectors" : [
                    {
                        "id" : "E",
                        "standard" : "IEC_62196_T1",
                        "last_updated" : ISODate("2021-02-18T23:54:56.000Z")
                    }
                ],
                "last_updated" : ISODate("2021-02-18T23:54:56.000Z")
            }
        ],
        "last_updated" : ISODate("2021-12-14T23:42:06.000Z")
    },
    {
        "id" : "F",
        "name" : "5th Avenue",
        "last_updated" : ISODate("2022-01-12T13:12:01.000Z")
    }
]

I have my query working for the top level last_updated field and the evses.last_updated field, but I am having trouble modifying the evses.connectors.last_updated field. This is my query:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

db.collection.aggregate([
    {
        $addFields: {
            last_updated: { $dateToString: { format: '%Y-%m-%dT%H:%M:%SZ', date: '$last_updated' } },
            evses: {
                $map: {
                    input: '$evses',
                    as: 'evse',
                    in: {
                        {
                            $mergeObjects: [
                                '$$evse',
                                { last_updated: { $dateToString: { format: '%Y-%m-%dT%H:%M:%SZ', date: '$$evse.last_updated' } } }
                            ]
                        }
                    }
                }
            }
        }
    }
])

Is it possible to do another $map within the $map.in object? I was able to get this working by turning in into an array, but this changed the way the data was returned.

Here is an example of my query using $map.in as an array:

db.collection.aggregate([
    {
        $addFields: {
            last_updated: { $dateToString: { format: '%Y-%m-%dT%H:%M:%SZ', date: '$last_updated' } },
            evses: {
                $map: {
                    input: '$evses',
                    as: 'evse',
                    in: [
                        {
                            $mergeObjects: [
                                '$$evse',
                                { last_updated: { $dateToString: { format: '%Y-%m-%dT%H:%M:%SZ', date: '$$evse.last_updated' } } }
                            ]
                        },
                        {
                            $map: {
                                input: '$$evse.connectors',
                                as: 'connector',
                                in: {
                                    $mergeObjects: [
                                        '$$connector',
                                        { last_updated: { $dateToString: { format: '%Y-%m-%dT%H:%M:%SZ', date: '$$connector.last_updated' } } }
                                    ]                              
                                }
                            }                    
                        }
                    ]
                }
            }
        }
])

In this case the returned documents look like this:

[
    {
        "id" : "A",
        "name" : "CHARGEPOINT WVCC 1684DELL 1",
        "evses" : [
            [
                {
                    "uid" : "B",
                    "connectors" : [
                        {
                            "id" : "C",
                            "standard" : "IEC_62196_T1",
                            "last_updated" : ISODate("2021-02-18T23:54:56.000+0000")
                        }
                    ],
                    "last_updated" : "2021-02-18T23:54:56Z"
                },
                [
                    {
                        "id" : "C",
                        "standard" : "IEC_62196_T1",
                        "last_updated" : "2021-02-18T23:54:56Z"
                    }
                ]
            ],
            [
                {
                    "uid" : "D",
                    "connectors" : [
                        {
                            "id" : "E",
                            "standard" : "IEC_62196_T1",
                            "last_updated" : ISODate("2021-02-19T22:15:43.000+0000")
                        }
                    ],
                    "last_updated" : "2021-02-19T22:15:43Z"
                },
                [
                    {
                        "id" : "E",
                        "standard" : "IEC_62196_T1",
                        "last_updated" : "2021-02-19T22:15:43Z"
                    }
                ]
            ]
        ],
        "last_updated" : "2021-12-14T23:42:06Z"
    },
    {
        "id" : "F",
        "name" : "5th Avenue",
        "last_updated" : "2022-01-12T13:12:01Z",
        evses: null
    }
]

Is it possible to perform a $map within another $map without duplicating the evses.connectors array and nesting them in another array?

>Solution :

Your query should be as below:

  1. Remove the [] from in for the $map.

  2. Merge objects for $$evse, last_updated document and connectors document.

db.collection.aggregate([
  {
    $addFields: {
      last_updated: {
        $dateToString: {
          format: "%Y-%m-%dT%H:%M:%SZ",
          date: "$last_updated"
        }
      },
      evses: {
        $map: {
          input: "$evses",
          as: "evse",
          in: {
            $mergeObjects: [
              "$$evse",
              {
                last_updated: {
                  $dateToString: {
                    format: "%Y-%m-%dT%H:%M:%SZ",
                    date: "$$evse.last_updated"
                  }
                }
              },
              {
                connectors: {
                  $map: {
                    input: "$$evse.connectors",
                    as: "connector",
                    in: {
                      $mergeObjects: [
                        "$$connector",
                        {
                          last_updated: {
                            $dateToString: {
                              format: "%Y-%m-%dT%H:%M:%SZ",
                              date: "$$connector.last_updated"
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading