[SERVER-14837] Positional Operator matching wrong nested document Created: 08/Aug/14  Updated: 17/Feb/15  Resolved: 03/Sep/14

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Raul E Rangel Assignee: Ramon Fernandez Marina
Resolution: Duplicate Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-14662 Positional projection queries (and po... Closed
is duplicated by SERVER-17301 Subcollection update does not work. Closed
Related
related to SERVER-11537 Incosistent behavior with $or and $el... Closed
related to SERVER-14886 Updates against paths composed with a... Closed
Operating System: ALL
Steps To Reproduce:

I've put together a gist that can be used to reproduce the problem: https://gist.github.com/ismell/9ae5a9798ae82a1a85de

As you can see in the results for 2.4 and 2.6 it's selecting the wrong sub document. It seems like its using the index of the dimensions array as the positional index instead of the position matched by the values._id clause.

Participants:

 Description   

When upgrading from mongo 2.4 to 2.6 the positional operator is matching the incorrect sub document. This causes an update query to incorrectly update the wrong value. The query supplied was produced by Mongoid when using doubly nested models. https://github.com/mongoid/mongoid/issues/3611 is the reported issue.



 Comments   
Comment by Raul E Rangel [ 02/Oct/14 ]

Just for people looking at this ticket. There is another ticket that is currently open: SERVER-14886

Comment by Ramon Fernandez Marina [ 03/Sep/14 ]

ismell, unfortunately I don't think is possible to have the same query work for 2.4 and 2.6 if the query has multiple predicates over arrays. For 2.6 you may want to rely on the deterministic, documented behavior. If you want to explore further options you could post on the mongodb-user group or Stack Overflow with the mongodb tag. A question like this involving more discussion would be best posted on the mongodb-user group.

Regards,
Ramón.

Comment by Raul E Rangel [ 03/Sep/14 ]

Hey Ramón,
Mongoid will always generate the query from least specific to most specific criteria. It will never swap the more specific criteria with a lesser one. The expected behavior would be that the positional operator matches the most specific criteria.

Do you have a recommendation on how Mongoid should write the query so that it will work for both 2.4 and 2.6?

Thanks,
Raul

Comment by Ramon Fernandez Marina [ 03/Sep/14 ]

ismell, the value of the positional operator when a query has multiple predicates over array fields may be ambiguous in 2.4. In your use case, when you query for

db.bug.update({
  "_id":ObjectId('53e29d8473636f0664000000'),
  "dimensions._id":ObjectId('53e29d8473636f06640c0000'),
  "dimensions.2.values._id":ObjectId('53e29d8473636f06640e0000')
}, ...

the positional operator takes the value 0 as you were expecting, but note that if you change the order of the predicates as follows

db.bug.update({
  "_id":ObjectId('53e29d8473636f0664000000'),
  "dimensions.2.values._id":ObjectId('53e29d8473636f06640e0000'),
  "dimensions._id":ObjectId('53e29d8473636f06640c0000')
}, ...

the positional operator takes the value 2, so if you're using 2.4 you should be aware of this behavior. In 2.6 the value of the positional operator in these cases was made deterministic as described in the documentation, which explains the behavior you describe.

That being said, this same issue has been reported before in SERVER-14662 and there may be some room for improvement, so please tune in to SERVER-14662 for further updates.

Regards,
Ramón.

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