Skip to content

Instantly share code, notes, and snippets.

@RobertLowe
Created March 9, 2018 14:46
Show Gist options
  • Save RobertLowe/80bd3c65ddd2a8570d8d382615b5ac7b to your computer and use it in GitHub Desktop.
Save RobertLowe/80bd3c65ddd2a8570d8d382615b5ac7b to your computer and use it in GitHub Desktop.
Meteor <-> Mongo, positional operator caution

This is poor behaviour from Mongo, and sorta fixed in 3.6 via the $[] operator (which is coming in Meteor 1.6.2), you should verify your apps aren't effected

But, $ probably isn't working as expected (in some cases)

$ | Acts as a placeholder to update the first element that matches the query condition.

https://docs.mongodb.com/manual/reference/operator/update-array/#update-operators

Docs are correct, but consider this example:

We have a document like:

 {
   _id: "foo",
   array: [
     {query: "thing", target: "hit"},
     {query: "thing", target: "me"},
     {query: "thing", target: "me"},
     {query: "thing", target: "hit"}
   ]
 }

And we update with:

{
    _id: "foo",
    "array.$.query" : 'thing',
    "array.$.target" : 'me',
}
{
    $set: {
        "array.$.target" : "hit"
    }
}

Will not target.

Alternatively without $ in the query clause with:

{
    _id: "foo",
    "array.query" : 'thing',
    "array.target" : 'me',
}
{
    $set: {
        "array.$.target" : "hit"
    }
}

Will update target of the array[1], but not array[2].

TLDR: Mongo plucks only the first element matching to change, and additionally, $ is not a valid query operator, so it's ignored / doesn't work.

...go home Mongo you're drunk! xD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment