1

Lets say here is the same document:

{
"_id" : 1.0,
"custname" : "metlife",
"address" : {
    "city" : "Bangalore",
    "country" : "INDIA"
 }
}

And if I want to push an extra field to this document, something like below:

db.customers.updateMany(
  {"address.country":"INDIA"},
  {$push : {city: "$address.country"}}

)

It results in wrong update:

{
"_id" : 1.0,
"custname" : "metlife",
"address" : {
    "city" : "Bangalore",
    "country" : "INDIA"
 },
 "city" : "$address.city"
}

Instead of this:

{
"_id" : 1.0,
"custname" : "metlife",
"address" : {
    "city" : "Bangalore",
    "country" : "INDIA"
 },
 "city" : "Bangalore"
}

How do I achieve the above result?

Rahul Raj
  • 3,197
  • 5
  • 35
  • 55

3 Answers3

1

You can't refer to other field values in update currently (more here). There is a workaround in aggregation framework (using $out) but it will replace entire collection.

I think that you can consider using $rename in your case. It will not add new field but it can move city to the top level of your document.

db.customers.updateMany({"address.country":"INDIA"}, {$rename: {"address.city": "city"}})

will give you following structure:

{ "_id" : 1, "custname" : "metlife", "address" : { "country" : "INDIA" }, "city" : "Bangalore" }
mickl
  • 48,568
  • 9
  • 60
  • 89
0

like @mickl said : You can't refer to other field values in update currently, you have to iterate through your collection to update the documents, try this :

db.eval(function() { 
    db.collection.find({"address.country":"INDIA"}).forEach(function(e) {
        e.city= e.address.city;
        db.collection.save(e);
    });
});

Keep in mind that this will block the DB until all updates are done.

Taki
  • 17,320
  • 4
  • 26
  • 47
-1

try this

db.customers.updateMany(
  {"address.country":"INDIA"},
  {$push : {city: "address.country"}}

)

remove $ sign

Gowtham Sooryaraj
  • 3,639
  • 3
  • 13
  • 22