1

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

The 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
  • are you trying to upsert into embedded document "tin" ? Commented Dec 13, 2016 at 1:57

1 Answer 1

2

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
        }]
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.