0

I have a table with data like

 {
  _id: ....
  Name
  ...
 "RoomStatusDetails": [
 {
   "StatusEntryId": ObjectId("5bd6ea81d2ccda0a780054da"),
   "RoomId": "78163a07-76db-83c1-5c22-0749fab73251",
   "CurrentStatus": ObjectId("5bd17295d2ccda11f0007765"),
   "StartDate": ISODate("2018-10-09T22:00:00.0Z"),
   "Notes": "Notes for in service",
   "Discrepancy": "Discrepency",
   "Waiver": "Waiver",
   "TFlight": "T Flight",
   "IsActive": "Inactive" 
},
 {
   "StatusEntryId": ObjectId("5bd6ecf3d2ccda0a780054db"),
   "RoomId": "78163a07-76db-83c1-5c22-0749fab73251",
   "CurrentStatus": ObjectId("5bd17295d2ccda11f0007766"),
   "StartDate": ISODate("2018-10-16T22:00:00.0Z"),
   "Notes": "Out of service",
   "Discrepancy": "",
   "Waiver": "",
   "TFlight": "",
   "IsActive": "Active" 
    },
    ...
   }

I have written below lines of code for updating IsActive field to "Inactive" on the basis of RoomId

       $this->collection->updateOne(array('_id' => new MongoDB\BSON\ObjectID($this->id), "RoomStatusDetails" => 
                  array('$elemMatch' => array("RoomId" => $this->RoomId))),
                  array('$set' => array("RoomStatusDetails.$.IsActive" => 'Inactive')), array("multi" => true, "upsert" => false));

The above code is not updating all the IsActive field. Please help!!!

Nida Amin
  • 735
  • 1
  • 8
  • 28

2 Answers2

2

You have to use arrayFilters to pass in the room id filter. Without arrayFilters it will update all [] the "RoomStatusDetails" array elements without taking into account the room id query filter.

Something like

 db.col.update(
   {"RoomStatusDetails.RoomId" :"78163a07-76db-83c1-5c22-0749fab73251"},
   {"$set":{"RoomStatusDetails.$[room].IsActive" : "Inactive"}}, 
   {"arrayFilters":{"room.RoomId":"78163a07-76db-83c1-5c22-0749fab73251"}}
);

In php

$bulkbatchStatus->update(
  array('_id' => new MongoDB\BSON\ObjectID($this->id), "RoomStatusDetails" => array('$elemMatch' => array("RoomId" => $this->RoomId))), 
  array('$set' => array("RoomStatusDetails.$[room].IsActive" => 'Inactive')), 
  array("multi" => true, "upsert" => false, "arrayFilters" => array("room.RoomId" => $this->RoomId))
);
s7vr
  • 73,656
  • 11
  • 106
  • 127
  • It does not work and does not throw any error message... – Nida Amin Oct 29 '18 at 18:38
  • Can you show me your query ? – s7vr Oct 29 '18 at 18:39
  • $bulkbatchStatus = new MongoDB\Driver\BulkWrite(['ordered' => true]); $bulkbatchStatus->update( array('_id' => new MongoDB\BSON\ObjectID($this->id), "RoomStatusDetails" => array('$elemMatch' => array("RoomId" => $this->RoomId))), array('$set' => array("RoomStatusDetails.$[room].IsActive" => 'Inactive')), array("multi" => true, "upsert" => false, "arrayFilters" => array("room.RoomId" => $this->RoomId)) ); – Nida Amin Oct 29 '18 at 18:39
  • I don't see anything wrong with the query. Can you make sure the passed arguments are correct and have a matching document meeting the query criteria in db ? – s7vr Oct 29 '18 at 18:42
  • the arguments are passed correctly.... – Nida Amin Oct 29 '18 at 18:46
  • Did you update your mongo server recently ? What is your mongo server version ? You may have to run `db.adminCommand( { setFeatureCompatibilityVersion: 3.6 } )` on mongo shell if you updated from 3.4 to 3.6. – s7vr Oct 29 '18 at 18:48
  • i am using 3,6 version – Nida Amin Oct 29 '18 at 18:49
  • Please help !!! it is very difficult to analyse the problrm – Nida Amin Oct 29 '18 at 18:58
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/182741/discussion-between-veeram-and-nida-amin). – s7vr Oct 29 '18 at 18:59
  • Any luck with the issue ? – s7vr Oct 31 '18 at 11:52
1

All matched embedded document:

For updating all matched embedded documents you should use $[] because $ refer the first position of matched embedded document.

the positional $ operator acts as a placeholder for the first element that matches the query document

Hardik Shah
  • 4,042
  • 2
  • 20
  • 41
  • thankyou so much.... – Nida Amin Oct 29 '18 at 14:25
  • @NidaAmin Most welcome! – Hardik Shah Oct 29 '18 at 14:26
  • after completing certain things i realised that it is not updating on the basis of roomid... it is updating other rooms status to inactive... please help – Nida Amin Oct 29 '18 at 18:14
  • / Add new if status changes $bulkbatchStatus = new MongoDB\Driver\BulkWrite(['ordered' => true]); $bulkbatchStatus->update(array('_id' => new MongoDB\BSON\ObjectID($this->id), "RoomStatusDetails" => array('$elemMatch' => array("RoomId" => $this->RoomId))), array('$set' => array("RoomStatusDetails.$[].IsActive" => 'Inactive')), array("multi" => true, "upsert" => false)); – Nida Amin Oct 29 '18 at 18:16
  • If you want specific matched but multiple documents then check Veeram answer. – Hardik Shah Oct 29 '18 at 18:24
  • I tried that it also does not work... please help!! – Nida Amin Oct 29 '18 at 18:29
  • it throws Call to undefined method MongoDB\Collection::update() in – Nida Amin Oct 29 '18 at 18:30