JVG
JVG

Reputation: 21150

MongoDB Shell: Is it possible do an update query using a function?

I have a collection with data like this:

[{
    _id: 1,
    address: '1/23 Fake Street'
},
{
    _id: 2,
    address: '5/20 Whatever Lane'
},
{
    _id: 3,
    address: '10 Foo Avenue'
}]

I'd like to perform a Mongo bulk update query, which does the following:

  1. Transforms the address field to lowercase
  2. Creates a new field, 'buildingAddress', which splits an address at the slash (if present, as with the first two items) and uses the text after it to populate the new field

In Node, I'd do something like this:

  const cursor = db.items.find({});

  for await (const item of cursor) {
    try {
      await pageMapper(item);
    } catch (e) {
      console.error(e);
    }
  }

async function pageMapper(item){
   const newAddress = item.address.toLowerCase()
   const buildingAddress = newAddress.split('/ ')[1];

   return db.items.updateOne(item._id, {
      $set: { 
         address: newAddress, 
         buildingAddress
       }
   })
}

I'm wondering if there's a way to do this in the MongoDB shell itself, passing in a function to db.collection.update? Or should I stick to the node driver for doing more complex update operations?

Upvotes: 0

Views: 190

Answers (1)

Joe
Joe

Reputation: 28316

If you are using MongoDB 4.2+, you can use aggregation or the pipeline form of update to accomplish that.

$toLower converts a string to lower case

$split to split the field

$slice or $arrayElemAt to pick the element(s) to keep

One possible way to do that with update:

db.items.updateMany({},[
    {$addFields:{ 
      address:{$toLower:"$address"}
    }},
    {$addFields:{
        buildingAddress:{
            $arrayElemAt:[
                {$split:["$address","/"]},
                -1
            ]
        }
     }}
])

Upvotes: 2

Related Questions