使用MongoDB更新数组

3

我有一个类似以下的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: 存储在数据库中的字段不能以 '$' 开头(不良密钥:'$push')

当我使用以下内容时:
db.update( updateQuery, updateCommand, true, true );

我收到了以下异常:

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

我尝试过: db.updateMulti(updateQuery, updateCommand); 我既没有得到任何异常,也没有进行任何文档更新。
那么我错过了什么吗!!
1个回答

14
save() 方法失败是因为它试图将以下文档插入到集合中:{"$push":{"resources":[一系列资源]}}, 而 "$push" 不是一个有效的键名。
从您的问题中,似乎您正试图向嵌入在 "itemList" 中、匹配 {"itemID": "1"} 的嵌入式文档内部的嵌入式文档列表 "resources" 添加另一个资源文档。这样对于处理嵌套文档层级是比较棘手的,但是它是可行的:
以下是如何使用 JS shell 将以下文档插入到 "resources" 列表中的方法:
> 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 从已发布的代码中看来,“resources”是一个列表。你可能需要使用的方法是$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驱动程序更新Mongo嵌入式文档的理解。我注意到这个问题也与Spring有关("mongoOperations"是Spring包中的一个类),而我不熟悉Spring。如果您在更新方面仍然遇到问题,也许社区中更熟悉Spring的其他成员可以提供帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接