Search code examples
javamongodbmorphianosql

morphia : upsert on Object embedded in an array


Using Morphia, is it possible to perform a saveOrUpdate / upsert operation on an object embedded inside an array.

Consider the following document :

{
_id : "abcd",
myArray : [{
        "key" : "areaTotal",
        "value" : "101.9",
        "label" : "Total area (municipality)"
    }, {
        "key" : "areaUrban",
        "value" : "803",
        "label" : "Total area (urban)"
    }, {
        "key" : "populationDensity",
        "value" : "15991",
        "label" : "Population desnsity"
    }
]
}

Is there a clean way to replace for example array element with key "areaUrban" by another object such as

{
        "key" : "areaUrban",
        "value" : "123",
        "label" : "a new label"
}

For now I do it in two update operations first delete, then add :

UpdateOperations<T> ops = createUpdateOperations().removeAll("myArray ", new BasicDBObject("key", "areaUrban")); 
update(createQuery().field("_id").equal(myObjId),ops);
UpdateOperations<T> ops2 = createUpdateOperations().add("myArray ", myReplacementObject); 
update(createQuery().field("_id").equal(myObjId),ops2);

Which works fine but can I do it in only one update op (either with morphia or with plain mongo java driver) ?

Also if a matching object did not originally exist in the array, then the myReplacementObject object should just be added to the array.

thanks


Solution

  • With the $ positional operator:

    db.test.update({_id: "abcd", "myArray.key": "areaUrban"}, {$set: {"myArray.$.value": 123, "myArray.$.label": "a new label"}})
    


    [Edit] As JohnnyHK mentions in the comments this won't upsert the nested document if it doesn't exist.