Updating nested array document in MongoDB

瘦欲@ 提交于 2019-12-11 07:59:17

问题


So I have a mongo document like this and i need to update the array based on the val

{
"_id" : NumberLong(222),
"pattern":"grain"
"BASIC" : {
    "frame":"clear"
    "tin" : [ 
        {
            "val" : "abc",
            "unit" : NumberLong(2311)
        }, 
        {
            "val" : "def",
            "unit" : NumberLong(2311)
        }, 
    ]
}
}

here is the code i've tried

        collection = db.getCollection("test");
    Bson where = new Document().append("_id", 222).append("BASIC.tin.val","abc");

     Bson update = new Document()
                .append("BASIC.tin.$.val", "xyz");
     Bson set = new Document().append("$set", update);
        try {

            UpdateResult result = collection.updateOne(where , set, new UpdateOptions().upsert(true));

            if(result.getMatchedCount()>0){
                System.out.println("updated");
                System.out.println(result.getModifiedCount());
            }else{
                System.out.println("failed");
            }
        } catch (MongoWriteException e) {
          e.printStackTrace();
        }

update works fine but does not upsert if the find fails This is the error which i get:

com.mongodb.MongoWriteException: The positional operator did not find the match needed from the query. Unexpanded update: BASIC.tin.$.val at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:558) at com.mongodb.MongoCollectionImpl.update(MongoCollectionImpl.java:542)


回答1:


The upsert into the embedded documents is not possible and hence the error. So to simulate upsert for embedded documents, you'll need to update your code like below. This checks for the modified count and if its 0 then it means we need to insert a new document in the embedded documents which makes use of push for this. This will do an upsert with "pqr" as val and "unit" as 400 for the example docs you have.

Bson where = new Document().append("_id", 222).append("BASIC.tin.val","pqr");

Bson update = new Document()
        .append("BASIC.tin.$.val", "xyz");
Bson set = new Document().append("$set", update);

try {

    UpdateResult result = collection.updateOne(where , set, new UpdateOptions());

    if(result.getModifiedCount() > 0){
        System.out.println("updated");
    } else if(result.getModifiedCount()==0){
          System.out.println("upserting");
          Bson where1 = new Document().append("_id", 222);
          Bson upsert = new Document().append("BASIC.tin", new Document().append("val", "pqr").append("unit", 400));;
          Bson push = new Document().append("$push", upsert);
          UpdateResult result1 = collection.updateOne(where1 , push, new UpdateOptions());
          if(result1.getModifiedCount() == 1)
              System.out.println("upserted");
    }else {
        System.out.println("failed");
    }
} catch (MongoWriteException e) {
  e.printStackTrace();
}

Sample Response after upsert

{
    "_id": NumberLong(222),
    "pattern": "grain",
    "BASIC": {
        "frame": "clear",
        "tin": [{
            "val": "xyz",
            "unit": NumberLong(2311)
        }, {
            "val": "def",
            "unit": NumberLong(2311)
        }, {
            "val": "pqr",
            "unit": 400
        }]
    }
}


来源:https://stackoverflow.com/questions/41112404/updating-nested-array-document-in-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!