Updating an array with MongoDB

I have JSON like:

{"_id": "1", "_class": "com.model.Test", "itemList": [{"itemID": "1", "itemName": "Foo", "resources": [{" resourceID ":" 1 "," resourceName ":" Foo Test1 ",}, {" resourceID ":" 2 "," resourceName ":" Foo Test2 ",}]}]}

I need to update the resource list. I did the following:

    BasicDBObject updateQuery = new BasicDBObject();
    updateQuery.put("id", "1");

    BasicDBObject updateCommand = new BasicDBObject();

    List<Resource> resources = populateResources();//Fetch a new list of Resources
    updateCommand.put("$push", new BasicDBObject("resources", resources));


    MongoOperations mongoOperations = mongoConfiguration.getMongoTemplate();
    DBCollection db = mongoOperations.getCollection("myCollection");
    db.save(updateCommand);

      

I am getting the following error:

java.lang.IllegalArgumentException: fields stored in db cannot start with '$' (Bad Key: '$ push')

When I used:

db.update( updateQuery, updateCommand, true, true );

      

I got the following exception:

java.lang.IllegalArgumentException: cannot serialize class com.model.Test

I've tried: db.updateMulti (updateQuery, updateCommand); I didn't get any exceptions or any updates to the docs.

So what I am missing here !!

+3


source to share


1 answer


The save () method does not work because it tries to insert the following document into the collection: {"$ push": {"resources": [resource list]}} and "$ push" is not a valid key name.

From your question, it seems that you are trying to add another resource document to the inline document list "resources" inside an inline document mapping {"itemID": "1"} inside "itemList" ". Is that correct?

Working with embedded document layers is tricky, but it can be done:
Here's how the following document can be inserted into the "resources" list using the JS wrapper:

> var docToInsert = { "resourceID" : "3", "resourceName" : "Foo Test3"}
> db.myCollection.update({_id:"1", "itemList.itemID":"1"}, {"$push":{"itemList.$.resources":docToInsert}})
> db.myCollection.find().pretty()
{
    "_class" : "com.model.Test",
    "_id" : "1",
    "itemList" : [
        {
            "itemID" : "1",
            "itemName" : "Foo",
            "resources" : [
                {
                    "resourceID" : "1",
                    "resourceName" : "Foo Test1"
                },
                {
                    "resourceID" : "2",
                    "resourceName" : "Foo Test2"
                },
                {
                    "resourceID" : "3",
                    "resourceName" : "Foo Test3"
                }
            ]
        }
    ]
}
> 

      

Documentation on using the "$" positional operator to update inline documents can be found in the "Update" documentation: http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

The documentation for the $ push modifier is also on the Update page: http://www.mongodb.org/display/DOCS/Updating#Updating-%24push



From the code posted, it appears that "resources" is a list. It is possible that the method you need to use is $ pushAll, used to add multiple values ​​to the list: http://www.mongodb.org/display/DOCS/Updating#Updating-%24pushAll

Using a Java driver, the above insertion can be done like this:

Mongo m = new Mongo("localhost", 27017);
DB db = m.getDB("test");
DBCollection myColl = db.getCollection("myCollection");

BasicDBObject docToInsert = new BasicDBObject("resourceID", "3");
docToInsert.put("resourceName", "Foo Test3");

BasicDBObject updateQuery = new BasicDBObject("_id", "1");
updateQuery.put("itemList.itemID", "1");

BasicDBObject updateCommand = new BasicDBObject("$push", new BasicDBObject("itemList.$.resources", docToInsert));

myColl.update(updateQuery, updateCommand);
System.out.println(myColl.findOne().toString());

      

The above produces the following:

{ "_class" : "com.model.Test" , "_id" : "1" , "itemList" : [ { "itemID" : "1" , "itemName" : "Foo" , "resources" : [ { "resourceID" : "1" , "resourceName" : "Foo Test1"} , { "resourceID" : "2" , "resourceName" : "Foo Test2"} , { "resourceID" : "3" , "resourceName" : "Foo Test3"}]}]}

      

Hopefully the above will improve your understanding of how updating an inline document works with Mongo using the Java driver. I notice that this question is also related to Spring ("mongoOperations" is a class from the Spring package), which I am unfortunately not familiar with. If you are still having problems updating, another community member who is more familiar with Spring may help.

+14


source







All Articles