Karine
Karine

Reputation: 621

MongoDB Update array in a document

I try to update arrays of multiple document with this query :

db.BusinessRequest.update({"DealTypes": { $exists: true }, "DealTypes.DisplayName": "Minority trade sale" }, {$set:{"DealTypes.$.DisplayName":"Minority"}}, false,true );

but when there is a match, it only updates the first row of my array whereas the displayName does not match with the first.

I use IntelliShell of MongoChef software.

My document looks like this :

{ 
"_id" : BinData(4, "IKC6QJRGSIywmKTKKRfTHA=="), 
"_t" : "InvestorBusinessRequest", 
"Title" : "Business Request 000000002", 
"DealTypes" : [
    {
        "_id" : "60284B76-1F45-49F3-87B5-5278FF49A304", 
        "DisplayName" : "Majority", 
        "Order" : "001"
    }, 
    {
        "_id" : "64A52AFE-2FF5-426D-BEA7-8DAE2B0E59A6", 
        "DisplayName" : "Majority trade sale", 
        "Order" : "002"
    }, 
    {
        "_id" : "C07AE70D-4F62-470D-BF65-06AF93CCEBFA", 
        "DisplayName" : "Minority trade sale", 
        "Order" : "003"
    }, 
    {
        "_id" : "F5C4390A-CA7D-4AC8-873E-2DC43D7F4158", 
        "DisplayName" : "Equity fund raising", 
        "Order" : "004"
    }
]

}

How can I achieve this please ? Thanks in advance

EDIT : This line works :

db.BusinessRequest.update({"DealTypes": { $exists: true }, "DealTypes": { $elemMatch: {"DisplayName": "Majority trade sale"}}}, {$set:{"DealTypes.$.DisplayName":"Majority"}}, false,true );

Upvotes: 0

Views: 2955

Answers (3)

Pratik Gujarathi
Pratik Gujarathi

Reputation: 965

Please try this :

db.BusinessRequest.find().forEach( function(doc) {
  do {
    db.BusinessRequest.update({{"DealTypes": { $exists: true }, "DealTypes.DisplayName": "Minority trade sale" },
                         {$set:{"DealTypes.$.DisplayName":"Minority"}});
  } while (db.getPrevError().n != 0);
})

or

You cannot modify multiple array elements in a single update operation. Thus, you'll have to repeat the update in order to migrate documents which need multiple array elements to be modified. You can do this by iterating through each document in the collection, repeatedly applying an update with $elemMatch until the document has all of its relevant comments replaced.

db.BusinessRequest.update({"DealTypes": { $exists: true }, "DealTypes": { $elemMatch: {"DisplayName": "Majority trade sale"}}}, {$set:{"DealTypes.$.DisplayName":"Majority"}}, false,true );

If you need efficiency in the search then I suggest you to normalise schema where each row is kept in separate document.

Upvotes: 2

ManishVerma
ManishVerma

Reputation: 36

Please execute the following script in your mongo shell :

db.BusinessRequest.find({"DealTypes":{$exists:true}}).forEach(function(item)
{

for(i=0;i < item.DealTypes.length;i++)
{
    if(item.DealTypes[i].DisplayName === 'Minority trade sale'){
        item.DealTypes[i].DisplayName = 'Minority';
    }
}
db.BusinessRequest.save(item);
});

Upvotes: 2

erolkaya84
erolkaya84

Reputation: 1849

Last two arguments in your update have a problem.

This is the form of update() method in mongodb

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

I believe your update should be like this;

db.BusinessRequest.update
( {"DealTypes": { $exists: true }, "DealTypes.DisplayName": "Minority trade sale" }
, {$set:{"DealTypes.$.DisplayName":"Minority"}}
{ upsert : false, multi : true });

Upvotes: 0

Related Questions