4

I'm trying to use array filters in mongodb 3.6.0-rc3, exactly like in doc example but not getting any rows affected and no error.

Example is simplified. I know this can be done with $ as positional operator but I'm planing to use this feature for two level nested arrays.

db.getCollection('books').update({},
    {
        $set: { "authors.$[element].firstName": "Joe" }
    },
    {
        arrayFilters: [ { element: { "_id": ObjectId("some_id") } } ],
        multi: true
    })

Anyone tried this yet?

Senad Mehic
  • 86
  • 1
  • 7
  • 2
    Is there something in the provided answer that you believe does not address your question? If so then please comment on the answer to clarify what exactly needs to be addressed that has not. If it does in fact answer the question you asked then please note to [Accept your Answers](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) to the questions you ask – Neil Lunn Nov 13 '17 at 09:58

3 Answers3

10

Are you typing this in robomongo? It looks like it! If so it won't work. Read my note on Updating a Nested Array with MongoDB where I say this does not work in an "older shell" or anything based on it ( which robomongo is a shell based build ) because of the way the shell helper methods are currently implemented:

NOTE Somewhat ironically, since this is specified in the "options" argument for .update() and like methods, the syntax is generally compatible with all recent release driver versions.

However this is not true of the mongo shell, since the way the method is implemented there ( "ironically for backward compatibility" ) the arrayFilters argument is not recognized and removed by an internal method that parses the options in order to deliver "backward compatibility" with prior MongoDB server versions and a "legacy" .update() API call syntax.

So if you want to use the command in the mongo shell or other "shell based" products ( notably Robo 3T ) you need a latest version from either the development branch or production release as of 3.6 or greater.

So if you want to "play with" the release candidate, either use the bundled mongo shell with that version or simply run your code through any standard driver.

Community
  • 1
  • 1
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • Thanks @NeilLunn. I tried it first in Robo 3T 1.1.1 and got: `No array filter found for identifier 'element' in path 'authors.$[element].firstName'` then in MongoDB shell version v3.6.0-rc3: `WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })` – Senad Mehic Nov 13 '17 at 14:07
  • Installed mongo following this tutorial: https://docs.mongodb.com/master/tutorial/install-mongodb-on-ubuntu/ – Senad Mehic Nov 13 '17 at 14:38
  • @SenadMehic English may be a problem here. **Will not work in RoboMongo**. Use the [`mongo`](https://docs.mongodb.com/getting-started/shell/client/) shell instead. See also [Update nested subdocuments in MongoDB with arrayFilters](https://stackoverflow.com/a/47233482/2313887). And check `db.version()`, as you possibly updated a shell but not the server. Must be a 3.6 rc or a development release greater than 3.5.12 – Neil Lunn Nov 13 '17 at 19:32
  • Thanks, this has solved my issue, but somehow this error pop'd up only few times in robo3T with the same query being ran for couple of times, remaining all times I saw `Updated 0 record(s)` or `Updated 1 record(s)` though nothing got updated via robo3T !! – whoami - fakeFaceTrueSoul Nov 21 '19 at 01:02
2
db.getCollection('books').update({},
    {
        $set: { "authors.$[element].firstName": "Joe" }
    },
    {
        arrayFilters: [ { "element._id": ObjectId("some_id") } ],
        multi: true
    })
0

this BUG,just upgrade studio-3t version to 2018.6.1,use $ and arrayFilter OK.I try it in mongo4.0.4 and studio-3t