'Trim string values of whitespace, from an array of sub-documents with string field

On all documents of my collection I want to perform a $trim operation to a specific field of an object that is in an array.

Example:

{
  "_id" : ObjectId("53857680f7b2eb611e843a32"),
  "company": Testcompany
  "customer" :
      "name": Testuser,
      "addresses" : [
            {
                "_id" : ObjectId("5d6d2f96e3fdc8001077ac6c"), 
                "street" : "Teststreet.   ", 
                "houseNr" : "133", 
            },
            {
                "_id" : ObjectId("5d6d2f96e3fdc8001077ac7b"), 
                "street" : "    Simplestreet.   ", 
                "houseNr" : "12", 
            }
        ], 
}

In the example, I want to $trim all values of the field: "customer.addresses.street"

To answer the upcoming questions:

  1. I know the article you mentioned (Removing white spaces (leading and trailing) from string value) but theres no example how to do it within an array.

My problem is, how to access the attributes within an array, heres the example of plain values:

[{ $set: { category: { $trim: { input: "$category" } } } }],

  1. Yes, I want to update the values of all documents within the collection


Solution 1:[1]

One possible way to do:

db.YOUR_COLLECTION.find({}).forEach(
    function(doc) {
        db.Trim.update(
            { "_id":doc._id }, 
            { 
                "$set": {
                    "customer.addresses":doc.customer.addresses.map(
                        function(child) {
                            return Object.assign(
                                child,
                                { street: child.street.trim() }
                            )
                        }
                    )
                }
            }
        )
    }
)

Obs: Solution with Javascript Executed in MongoShell.

Solution 2:[2]

You can use $map and $trim in an updateMany aggregation pipeline like this :

db.YOUR_COLLECTION.updateMany({"customer.addresses":{$ne:null}},[
     {
            $set: {
                "customer.addresses":
                { 
                   $map: {
                          input: "$customer.addresses",
                          as: "address",
                          in: { $trim: { input: "$$address" } }
                        }
                 }
            }
    }
])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Haruo
Solution 2 Vincent Couturier