Question

I have a collection called "XX" and in this collection I have several documents. I am matching on the field "userEmail".

This is the structure of the document:

{ "_id" : { "$oid" : "5331e4e313163623bb649249"} ,
   "userEmail" : "user3@this.com"} 
   "reservations" : [ { 
        "idRest" : "23" , 
        "userPhone" : "88888888" , 
        "date" : "03-13-2015" , 
        "hour" : "14:30" 
   },
   { 
        "idRest" : "24" , 
        "userPhone" : "88888888" , 
        "date" : "03-13-2015" , 
        "hour" : "17:30" 
   },
   { 
        "idRest" : "22" , 
        "userPhone" : "88888888" , 
        "date" : "03-13-2015" , 
        "hour" : "16:30" 
  }]

}

And now I need find the document where "userEmail" = "some@some.com" and update the fields of the array where "idRest" = 24. in this case:

{ 
    "idRest" : "24" , 
    "userPhone" : "88888888" , 
    "date" : "03-13-2015" , 
    "hour" : "17:30" 
},

Can you help me please to build the query using JAVA driver :) thanks in advance!!


EDIT: this is my code, but instead of update the fields add a new sub document

`

DBCollection collReservationByUser = db.getCollection(usersReservationCollection);

DBObject queryx = new BasicDBObject("userEmail", rest.getEmailUser());

BasicDBObject document1 = new BasicDBObject();

document1.put("idRest", rest.getEmailUser());
document1.put("userPhone", rest.getPhoneUser());
document1.put("date", rest.getFecha());
document1.put("hour", rest.getHora());;

DBObject update1 = new BasicDBObject();
update1.put("$push", new BasicDBObject("reservations", document1));
collReservationByUser.update(queryx, update1, true, true);`
Was it helpful?

Solution

In the shell, you could do this using a command like:

db.XX.update(
    // Find the document where userEmail=some@some.com and find the element in the "reservations" array where idRest=24
    {
        "userEmail":"some@some.com", 
        "reservations.idRest":24
    }, 
    // Update the element matched by the find criteria with new values
    {
        $set:{
           "reservations.$.idRest":99, 
           "reservations.$.userPhone":"888888", 
           "reservations.$.date":"03-13-2015", 
           "reservations.$.hour":"17:30"
        }
    }
)

And the Java equivalent will look like:

    ...
    DBObject selectQuery = new BasicDBObject("userEmail", rest.getEmailUser());
    selectQuery.append("reservations.idRest", rest.getId());

    BasicDBObject updateFields = new BasicDBObject();
    updateFields.put("reservations.$.idRest", rest.getEmailUser());
    updateFields.put("reservations.$.userPhone", rest.getPhoneUser());
    updateFields.put("reservations.$.date", rest.getFecha());
    updateFields.put("reservations.$.hour", rest.getHora());;

    DBObject updateQuery = new BasicDBObject();
    updateQuery.put("$set", updateFields);
    collReservationByUser.update(selectQuery, updateQuery, true, true); 
    ...

Note: If the "reservations" array has multiple elements with "idRest"=24, then the above query will only update the first matched element. It's not possible to update multiple elements within an array using positional operator.

OTHER TIPS

Updating is not much different, see the .update() method in the documentation. But you will want the $set operator instead:

DBObject queryx = new BasicDBObject("userEmail", "some@some.com");
queryx.put("idRest", 24);


BasicDBObject document1 = new BasicDBObject();

document1.put("idRest", rest.getEmailUser());
document1.put("userPhone", rest.getPhoneUser());
document1.put("date", rest.getFecha());
document1.put("hour", rest.getHora());

DBObject update1 = new BasicDBObject();

update1.put("$set", new BasicDBObject("reservations.$", document1));
collReservationByUser.update(queryx, update1);`

You also do not need all the fields so to just update "userPhone" change to this:

BasicDBObject document1 = new BasicDBObject();
document1.put("reservations.$.userPhone", rest.getPhoneUser());

DBObject update1 = new BasicDBObject();

update1.put("$set", document1);
collReservationByUser.update(queryx, update1);`

This relies on the positional $ operator in order to work on the "matching" index of the array.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top