简体   繁体   中英

How to update an array item in MongoDB with two "where" condition using java driver

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);`

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM