1

I am using ObjCMongoDB as a cocoa wrapper for accessing mongoDB. I am facing difficulty in a scenario where I have to find and replace a document with a new document. Can any one help me by pointing out the code/API of ObjCMongoDB to use.

For example:

{
"_id" : { "$oid" : "51de4ed737965b2d233f4862"} ,
"milestone" : "Application 7.1 release" ,
"pendingtasklist" : [ task1 , task2 , task3]
}

here I have to replace pendingtasklist with new list and result should be

{
"_id" : { "$oid" : "51de4ed737965b2d233f4862"} ,
"milestone" : "Application 7.1 release" ,
"someotherlist" : [ task12 , task33 , task32]
}

I have attached the code I am using to achieve this, but without success

NSError *connectionError = nil;
MongoConnection *dbConn = [MongoConnection connectionForServer:@"127.0.0.1:27017" error:&connectionError];


MongoDBCollection *collection = [dbConn collectionWithName:@"mydb.milestones"];

MongoKeyedPredicate *predicate = [MongoKeyedPredicate predicate];
[predicate keyPath:@"milestone" matches:@"Application 7.1 release"];

MongoUpdateRequest *updateReq = [MongoUpdateRequest updateRequestWithPredicate:predicate  firstMatchOnly:YES];
NSDictionary *milestoneDict = @{@"problemlist": @[@"12345",@"112244",@"55543",@"009009"],@"milestone":@"Application 7.1 release"};
[updateReq replaceDocumentWithDictionary:milestoneDict];

BOOL result = [collection updateWithRequest:updateReq error:&connectionError];

Before my collection will have documents like this:

{ "_id" : { "$oid" : "51de4ed737965b2d233f4862"} , "milestone" : "Application 7.1 Release" , "problemlist" : [ 12345 , 112244 , 55543]}
{ "_id" : { "$oid" : "51de4ed737965b2d233f4864"} , "milestone" : "Application 7.1 UAT" ,  "problemlist" : [ 33545 , 7654 , 8767]}
Kiran Balegar
  • 916
  • 6
  • 16

2 Answers2

1

If the value were staying the same, you would just rename the key:

  • -[MongoUpdateRequest keyPath:renameToKey:]

But since the values are changing, you should just unset the old key and set the new one.

  • -[MongoUpdateRequest unsetValueForKeyPath:]
  • -[MongoUpdateRequest keyPath:setValue:]

As I mentioned above you can do this with a single update request.

paulmelnikow
  • 16,895
  • 8
  • 63
  • 114
  • 1
    The string for milestone doesn't match your sample data, which has an extra space before Release. To add values to an array, use -arrayForKeyPath:appendValuesFromArray: instead. What exactly is happening? What are the values of result, and of connectionError? – paulmelnikow Jul 25 '13 at 11:41
  • Basically in a my collection, I have lot of documents which has lot of key:values. In update I dont want to check each field in a document and write query to update the document. Instead I want to replace the document with a updated document which might have some new key:value added or deleted. Hope I am clear this time :) And the BOOL result will be YES but the DB is not getting updated. – Kiran Balegar Jul 25 '13 at 12:16
  • Found it! as u said there was a typo with my string and db document. Thanks a lot :) – Kiran Balegar Jul 25 '13 at 13:39
  • Is ObjCMongoDB thread safe? I have like 200 asynchronous operations executing and all of them has DB Insert/Update as their last task. Thanks! – Kiran Balegar Jul 29 '13 at 13:00
0

In order to rename a field, you need to remove the old one, and add the new one. In this case, you would have to run two separate queries for this.

Derick
  • 35,169
  • 5
  • 76
  • 99
  • First sentence yes; second sentence no. In Mongo, you can make multiple changes to a document with a single update request. – paulmelnikow Jul 24 '13 at 16:36