【问题标题】:Update an array using MongoDB使用 MongoDB 更新数组
【发布时间】:2012-04-07 12:03:07
【问题描述】:

我有 JSON 之类的:

{“_id”:“1”,“_class”:“com.model.Test”,“itemList”:[ {“itemID”:“1”,“itemName”:“Foo”, “资源”:[{“resourceID”:“1”,“resourceName”:“Foo Test1”,},{“resourceID”:“2”,“resourceName”:“Foo 测试2", } ] } ] }

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

    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); 我没有收到任何异常,也没有对文档进行任何更新。

那我错过了什么!!

【问题讨论】:

    标签: java spring mongodb


    【解决方案1】:

    save() 方法失败,因为它试图将以下文档插入到集合中:{"$push":{"resources":[a list of 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 驱动程序使用 Mongo 更新嵌入式文档。我注意到这个问题也与 Spring 有关(“mongoOperations”是 Spring 包中的一个类),不幸的是我不熟悉它。如果您的更新仍有问题,也许社区中另一位更熟悉 Spring 的成员将能够提供帮助。

    【讨论】:

    • 谢谢 Marc。这非常有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    相关资源
    最近更新 更多