2

I am currently using the $pull operator successfully to delete an item in an array. The Data structure looks like this

{
_id: 234,
comments: [{id:1},{id:2},{id:3}]
}

My change struct

change := mgo.Change{
    Update: bson.M{
        "$pull": bson.M{
            "comments": bson.M{
                "id": c.Id,
            },
        },
    },
    ReturnNew: true,
}

and my mongo command

test, err := cs.Find(bson.M{"_id": 234}).Apply(change, nil)

In the mongo shell, simulating the same command would return useful meta information

On success WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

on Fail WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

However in Go, the results of test is &{Updated:1 Removed:0 Matched:1 UpsertedId:<nil>}

regardless of whether it successfully updated anything or not. Of course if it can't find the Document, it will return an error, but if it finds the document but fails in the $pull request, it doesn't give me any sort of indication.

My Question: How can I determine whether an array modifier was successful or not without having to query the database a second time

Quest
  • 560
  • 4
  • 16
  • just to Clarify: `Updated:1` is returned regardless of whether anything was updated or not – Quest Feb 25 '16 at 21:37
  • 1
    FYI what \`\`\` does on github is done here by indenting the code block by four spaces (CTRL+K). – Tomalak Feb 25 '16 at 22:01
  • 1
    The reason the results are different are because the mgo driver still uses "legacy mode" updates, where as the `mongo` shell as well as some other drivers are actually using the [Bulk](https://docs.mongodb.org/manual/reference/method/Bulk/) API methods under the covers. This returns the different `WriteResult` structure. This is not yet implemented in mgo ( [Issue #146](https://github.com/go-mgo/mgo/issues/146) ), but as demonstrated there, you could use the command form with `Run()`. Not sure of the resulting BSON content and no time to play with it right now. But you might give that a try. – Blakes Seven Feb 25 '16 at 22:56
  • Also note that the `ReturnNew: true` in your code only really applies when used with `.Apply()` for a "findAndModfiy" behavior, and would not apply to commands issed in "Bulk" ( even as one ). So it depends on what you want to do. If you really want the returned document as with "findAndModify", then simply inspecting the returned document would prove sufficient test of whether the `$pull` was applied or not. i.e The "pulled" element(s) would no longer be in the array. – Blakes Seven Feb 25 '16 at 23:00

0 Answers0