[SERVER-16393] Positional array projection returns wrong results for _id hack queries Created: 02/Dec/14  Updated: 10/Dec/14  Resolved: 02/Dec/14

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

Type: Bug Priority: Minor - P4
Reporter: John Esmet Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Steps To Reproduce:

[esmet@celery mongo] $ ./mongo
MongoDB shell version: 2.4.10
connecting to: 127.0.0.1:29001/test
> db.test.drop()
> db.test.insert({"_id": 0,"subDocs":[{"id":1,"foo":"bar"},{"id":2,"foo":"baz"}]})
> db.test.find({ 'subDocs.id': 1 }, { 'subDocs.$': 1 })
{ "_id" : 0, "subDocs" : [  {  "id" : 1,  "foo" : "bar" } ] }
> db.test.find({ _id: 0 }, { 'subDocs.$': 1 })
{ "_id" : 0, "subDocs" : [  {   },  {   } ] } // oops!
> db.test.find({ _id: 0 })
{ "_id" : 0, "subDocs" : [  {  "id" : 1,  "foo" : "bar" },  {  "id" : 2,  "foo" : "baz" } ] }

Participants:

 Description   

The old 2.4.X query by _id hack code path doesn't pass a MatchDetails object to fillQueryResultFromObj, so the positional array projection feature (SERVER-828) doesn't do the right thing. See:

curop.debug().idhack = true;
if ( found ) {
    n = 1;
    fillQueryResultFromObj( bb, pq.getFields() , resObject ); // details stays the default NULL param value
}

The easiest thing to do would be to avoid the query by _id hack altogether for queries with a positional array projection.

Note: I do not think this bug exists in 2.6.X or 2.8.X but I haven't tried it.



 Comments   
Comment by John Esmet [ 02/Dec/14 ]

Thanks! That is a good explanation. I agree that having a better error message (as is the case in 2.6) is the right improvement. So there are probably no action items for this in 2.4.X

Comment by J Rassi [ 02/Dec/14 ]

I don't believe there is a bug here.

The positional operator is a placeholder for the offset in the array that was implicitly traversed during the match. It cannot be used when no array was implicitly traversed while matching the query predicate.

In line 6 of your example, the element "subDocs.0.id" was used for the match {"subDocs.id": 1}, so the request for element "subDocs.$" in the projection is translated to a request for "subDocs.0".

In line 8 of your example, no array was traversed during the match {_id: 1} (in fact, an array can never be traversed for a match on _id, since the _id field can't itself be an array), so the projection {"subDocs.$": 1} is invalid. 2.6 gives a nicer error for this case.

Let me know if there's anything I'm misunderstanding about your report.

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