使用MongoDB更新数组

时间:2012-04-07 12:03:07

标签: java spring mongodb

我有JSON之类的:

  

{“_ id”:“1”,“_ class”:“com.model.Test”,“itemList”:[   {“itemID”:“1”,“itemName”:“Foo”,            “resources”:[{“resourceID”:“1”,“resourceName”:“Foo Test1”,},{“resourceID”:“2”,“resourceName”:“Foo   Test2“,}]}}}

我需要能够更新资源列表。 我做了以下事情:

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

我得到了以下错误:

  

java.lang.IllegalArgumentException:db中存储的字段不能   以'$'开头(坏键:'$ push')

我用的时候:

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

我遇到以下异常:

  

java.lang.IllegalArgumentException:无法序列化类   com.model.Test

我试过了: db.updateMulti(updateQuery,updateCommand); 我没有得到任何例外,也没有任何更新发生在文件中。

所以我在这里错过了什么!!

1 个答案:

答案 0 :(得分:14)

save()方法失败,因为它试图将以下文档插入集合中:{“$ push”:{“resources”:[资源列表]}},而“$ push”不是有效的密钥名称。

从您的问题看来,似乎您正在尝试将另一个资源文档添加到嵌入文档列表中,“资源”,在“itemID”:“1”}内嵌入的文档内,在“itemList”中”。这是对的吗?

处理嵌入式文档的层次很棘手,但可以这样做:
以下是使用JS shell将以下文档插入“资源”列表的方法:

> 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"
                }
            ]
        }
    ]
}
> 

有关使用“$”位置运算符更新嵌入文档的文档,请参阅“更新”文档: http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

“$ push”修饰符的文档也在“更新”页面上: http://www.mongodb.org/display/DOCS/Updating#Updating-%24push

从发布的代码中,似乎“资源”是一个列表。您需要使用的方法是$ pushAll,用于向列表添加多个值: http://www.mongodb.org/display/DOCS/Updating#Updating-%24pushAll

使用Java驱动程序,可以这样完成上面的插入:

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

以上输出如下:

{ "_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"}]}]}

希望以上内容可以帮助您更好地了解如何使用Java驱动程序更新嵌入式文档。我注意到这个问题也与Spring有关(“mongoOperations”是Spring包中的一个类),我很遗憾不熟悉它。如果您仍然遇到更新问题,那么更熟悉Spring的社区的其他成员也许可以提供帮助。