It's much easier to modify the object you get from the database on the client side.
I am assuming here that the documents inside photos are ordered by the _id, if it's not the case you'll have to search inside the array, and thus have a few more steps.
First, here is how you do this in the mongo shell (JavaScript), but this should not be much different in Java:
> v = db.ppl.find({_id: "2894"}).next();
{
"_id" : "2894",
"_class" : "com.foo.Person",
"name" : "Pixel Spacebag",
"photos" : [
{
"_id" : 10,
"amount" : "100"
},
{
"_id" : 11,
"amount" : "200"
}
]
}
> v.photos[0]
{ "_id" : 10, "amount" : "100" }
> v.photos[0].distributor = "pixel studios"
> v.photos[0]
{ "_id" : 10, "amount" : "100" }
> v.photos[0].distributor = "pixel studios"
> db.ppl.update({_id:"2894"}, {$set : {"photos": v.photos}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.ppl.findOne()
{
"_id" : "2894",
"_class" : "com.foo.Person",
"name" : "Pixel Spacebag",
"photos" : [
{
"_id" : 10,
"amount" : "100",
"distributor" : "pixel studios"
},
{
"_id" : 11,
"amount" : "200"
}
]
}
So, where I am using . for assignment you'll have to use the appropriate get or set method with possible casting for the right type.
The following code is the Java equivalent for the JS I posted above:
Document example = new Document("_class", "com.foo.Person")
.append("_id", "2894")
.append("name", "Pixel Spacebag");
List<Document> photos = new ArrayList<Document>();
photos.add(new Document("_id", 10).append("amount", "100"));
photos.add(new Document("_id", 11).append("amount", "200"));
example.append("photos", photos);
collection.insertOne(example);
FindIterable<Document> res = collection.find(new Document("_id", "2894"));
Document temp = res.iterator().next();
List<Document> photosDoc = (List<Document>) temp.get("photos");
Document docToUpdate = photosDoc.get(0);
docToUpdate.append("distributor", "pixel studios");
photosDoc.set(0, docToUpdate);
collection.updateOne(new Document("_id", temp.get("_id")),
new Document("$set", new Document("photos", photosDoc)));
/* Check that everything worked */
res = collection.find(new Document("_id", "2894"));
Document updatedDocument = res.iterator().next();
System.out.println(updatedDocument);
/* outputs:
Document{{_id=2894, _class=com.foo.Person, name=Pixel Spacebag, photos=[Document{{_id=10, amount=100, distributor=pixel studios}}, Document{{_id=11, amount=200}}]}}
*/
$pushinto the array or keep it sorted. If it is not ordered, than my answer bellow will have a step of search and replace inside the array. But conceptually it stays the same.