[SERVER-4155] Index bound incorrect? Created: 26/Oct/11  Updated: 19/Aug/13  Resolved: 30/Mar/12

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

Type: Bug Priority: Minor - P4
Reporter: Kyle Banker Assignee: Aaron Staple
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
Operating System: ALL
Participants:

 Description   

This appears to be a floating point issue. Please confirm. Issue is here:
http://groups.google.com/group/mongodb-user/browse_thread/thread/b298eee9ef62cb1f



 Comments   
Comment by Aaron Staple [ 21/Aug/12 ]

Hi Jack - In 2.2+ you can use $elemMatch to get the ranges you want, see SERVER-4180.

Comment by Jack Xu [ 20/Aug/12 ]

in mongod 2.0+, when I run the following query in a single element multikey indexed document, it works fine and leverages multikey index:

db.objects.drop();
db.objects.save({attrib : [

{d : 3}

]})
db.objects.save({attrib : [

{d : 5}

]})
db.objects.save({attrib : [

{d : 7}

]})
db.objects.ensureIndex(

{attrib : 1}

)
db.objects.find({attrib: {$gt:

{d: 4}

, $lt:

{d: 6}

}}).explain();

{
"cursor" : "BtreeCursor attrib_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"attrib" : [
[

{ "d" : 4 }

,

{ "d" : 6 }

]
]
},
"server" : "lucid64:27017"
}

However, as soon as there are multiple elements in the array, one of the bounds is simply ignored!

db.objects.drop();
db.objects.save({attrib : [

{c : 'test'}

,

{d : 3}

]})
db.objects.save({attrib : [

{c : 'test1'}

,

{d : 5}

]})
db.objects.save({attrib : [

{c : 'test3'}

,

{d : 7}

]})
db.objects.ensureIndex(

{attrib : 1}

)
db.objects.find({attrib: {$gt:

{d: 4}

, $lt:

{d: 6}

}}).explain();

{
"cursor" : "BtreeCursor attrib_1",
"isMultiKey" : true,
"n" : 2,
"nscannedObjects" : 5,
"nscanned" : 5,
"nscannedObjectsAllPlans" : 5,
"nscannedAllPlans" : 5,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"attrib" : [
[

{ "d" : 4 }

,

{ "$maxElement" : 1 }

]
]
},
"server" : "lucid64:27017"
}

I just wonder why "we can't constrain the index on both upper and lower bounds", especially it is already working fine in 1.8.1.

Comment by Sergejs Degtjars [ 07/Aug/12 ]

Looks like this problem is more complicated: SERVER-6720

Comment by Eliot Horowitz (Inactive) [ 30/Mar/12 ]

The semantics wanted there are what $elemMatch are for.
I don't think changing the semantics of a query operator is a great idea at this point.

Comment by Kyle Banker [ 29/Mar/12 ]

Can we reconsider this?

Comment by Kyle Banker [ 29/Mar/12 ]

I think that we should reconsider this. Have a look at this issue:
https://groups.google.com/forum/?fromgroups#!topic/mongodb-user/3xfoqFW6uIA

The user make a good point:
What we want is that any one key matches BOTH criteria, not any key matches either.

In the example:
save

{a:[1,10]}

query {a:{$gt:2,$lt:9}}

I don't believe that the document should be returned. For example, what about this:
save (

{a: 1}

)
query {a:{$gt:2,$lt:9}}

In this case, both ranges are taken into account.

This may be a case where we need a new operator to account for both semantics, but I believe that both are reasonable. Arguably, users can get the current, v2.0 semantic like this:
query {$or: [

{a:$gt:2}

, {a: {$lt:9}}]}

Comment by Aaron Staple [ 27/Oct/11 ]

The behavior described is as designed, and is new in 2.0.

Because the index is multikey, we cannot constrain the index on both upper and lower bounds. Instead, only one of the bounds is chosen. This is so we can return correct matches in cases like the following:

save

{a:[1,10]}

query {a:{$gt:2,$lt:9}}

The document should be returned because both query criteria ($gt and $lt) match a value in the a array, but if we were to use both upper and lower index bounds we would not find this document using the index.

Right now if you want to do an index scan with both upper and lower bounds, you need to use a non multi key index.

At some point we may implement tighter index bounds for the related elemMatch query, potentially as part of SERVER-1264.

There is some additional discussion here: SERVER-958

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