[SERVER-14886] Updates against paths composed with array index notation and positional operator fail with error Created: 13/Aug/14  Updated: 11/Jul/16  Resolved: 20/Nov/14

Status: Closed
Project: Core Server
Component/s: Write Ops
Affects Version/s: 2.6.3, 2.6.4
Fix Version/s: 2.6.6, 2.8.0-rc1

Type: Bug Priority: Minor - P4
Reporter: Bersam Karbasion Assignee: J Rassi
Resolution: Done Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-16409 Updates against paths composed with a... Closed
Related
is related to SERVER-14837 Positional Operator matching wrong ne... Closed
is related to SERVER-16409 Updates against paths composed with a... Closed
Tested
Operating System: ALL
Backport Completed:
Steps To Reproduce:

I get that error on these queries:

db.music.update({ 'rounds.0.groups.0.teams.crawlerTeamId': '69',
  id: 'iranLeagueEvents-1393' }, {$set: { 'rounds.0.groups.0.teams.$.standing': 
   { crawlerTeamId: '70'} });

or this one StackOverFlow

db.music.update({genre : "Grunge", "bands.0.albums.0.tracks.order" : 1}, {$set:{"bands.0.albums.0.tracks.$.name":"Smells Like Teen Spirit!"}})

Sprint: Query 2.7.8
Participants:

 Description   

I'm using "$" positional per update in a project, It was working without any problem in Ubuntu (mongoDB 2.4), I cloned the project into Archlinux and i get this error on db.collection.update:

{ [MongoError: The positional operator did not find the match needed from the query. Unexpanded update: rounds.0.groups.0.teams.$.standing]
  name: 'MongoError',
  code: 16837,
  err: 'The positional operator did not find the match needed from the query. Unexpanded update: rounds.0.groups.0.teams.$.standing' }

while I'm sure that the find query always match only one object in mongoDB.
Seems the last version of mongoDB broke backward compatibility of this functionality.



 Comments   
Comment by Githook User [ 20/Nov/14 ]

Author:

{u'username': u'jrassi', u'name': u'Jason Rassi', u'email': u'rassi@10gen.com'}

Message: SERVER-14886 BSONElementIterator::next() set array offset correctly

(cherry picked from commit acc09c2ec26b27c6d201f5f98a2a9c7b4215b1ae)
Branch: v2.6
https://github.com/mongodb/mongo/commit/2fcb960cdaeda3e6f6d4295936926712d04c6dd4

Comment by Githook User [ 20/Nov/14 ]

Author:

{u'username': u'jrassi', u'name': u'Jason Rassi', u'email': u'rassi@10gen.com'}

Message: SERVER-14886 BSONElementIterator::next() set array offset correctly
Branch: master
https://github.com/mongodb/mongo/commit/acc09c2ec26b27c6d201f5f98a2a9c7b4215b1ae

Comment by J Rassi [ 13/Aug/14 ]

Thanks for the sample document. Please continue to watch this ticket for updates.

Comment by Bersam Karbasion [ 13/Aug/14 ]

@Jason
output is one object with more than 13k lines. I know this is too messy, but i just wondering about the issue on latest version of mongo. I cleaned up the output and removed private data:

{
    "rounds": [
        {
            "groups": [
                {
                    "name": "main",
                    "teams": [
                        {
                            "crawlerName": "iranLeague",
                            "crawlerTeamId": "69",
                            "id": "iranLeagueTeams-69",
                            "name": "استقلال تهران",
                            "standing": {
                                
                            }
                        } //, lot's of more objects was here
                    ]
                }
            ]
        }
    ]
}

Comment by J Rassi [ 13/Aug/14 ]

I'm able to reproduce this on 2.6.0 through 2.6.4. It looks like an issue that affects use of array index notation combined with use of the positional operator in an update path.

> db.foo.drop()
true
> db.foo.insert({a:[{b:[{c:1}]}]})
WriteResult({ "nInserted" : 1 })
> db.foo.update({"a.0.b.c": 1}, {$set: {"a.0.b.$.d": 2}})
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"writeError" : {
		"code" : 16837,
		"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: a.0.b.$.d"
	}
})
>

Note that the issue does not manifest if the positional operator precedes the array index in the update path:

> db.foo.update({"a.b.0.c": 1}, {$set: {"a.$.b.0.d": 2}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0 })
> db.foo.find()
{ "_id" : ObjectId("53eb9635e6f80479558d26b5"), "a" : [ { "b" : [ { "c" : 1, "d" : 2 } ] } ] }
>

I confirm these updates succeed correctly on 2.4.10.

Assigning to hari.khalsa@10gen.com for triage.

Comment by J Rassi [ 13/Aug/14 ]

Could you supply the output of running the following at the shell?

db.music.findOne({ 'rounds.0.groups.0.teams.crawlerTeamId': '69', id: 'iranLeagueEvents-1393' })

Comment by Bersam Karbasion [ 13/Aug/14 ]

I forgot to mention that the same code without a single change of code would work on mongoDB server version 2.4.

Generated at Thu Feb 08 03:36:16 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.