diff options
author | Aaron <aaron@10gen.com> | 2009-02-11 15:37:51 -0500 |
---|---|---|
committer | Aaron <aaron@10gen.com> | 2009-02-11 15:37:51 -0500 |
commit | c326d4a5086dfb2610c960cdedfe8735adc68376 (patch) | |
tree | 882af336ccc2b154a7bf5862ad0df3a13bc9f554 | |
parent | 878cffc529ec5987deacfc15b9dd919e79ae8248 (diff) | |
download | mongo-c326d4a5086dfb2610c960cdedfe8735adc68376.tar.gz |
Can pick index with more key specificity than required by sort / find spec
-rw-r--r-- | db/jsobj.cpp | 12 | ||||
-rw-r--r-- | db/jsobj.h | 3 | ||||
-rw-r--r-- | db/query.cpp | 20 | ||||
-rw-r--r-- | jstests/index7.js | 4 |
4 files changed, 30 insertions, 9 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp index 16bbbdd4b1f..e7c8862119c 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -739,6 +739,13 @@ namespace mongo { } return b.done(); } + + /** + sets element field names to empty string + If a field in pattern is missing, it is omitted from the returned + object. Unlike extractFieldsDotted, it does not return an empty + object on missing pattern field. + */ BSONObj BSONObj::extractFieldsUnDotted(BSONObj pattern) const { BSONObjBuilder b; BSONObjIterator i(pattern); @@ -747,9 +754,8 @@ namespace mongo { if ( e.eoo() ) break; BSONElement x = getField(e.fieldName()); - if ( x.eoo() ) - return BSONObj(); - b.appendAs(x, ""); + if ( !x.eoo() ) + b.appendAs(x, ""); } return b.obj(); } diff --git a/db/jsobj.h b/db/jsobj.h index 55bf59314a8..26b0a40dd0a 100644 --- a/db/jsobj.h +++ b/db/jsobj.h @@ -566,6 +566,9 @@ namespace mongo { /** sets element field names to empty string + If a field in pattern is missing, it is omitted from the returned + object. Unlike extractFieldsDotted, it does not return an empty + object on missing pattern field. */ BSONObj extractFieldsUnDotted(BSONObj pattern) const; diff --git a/db/query.cpp b/db/query.cpp index 33def1372ec..5195dea984a 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -58,11 +58,11 @@ namespace mongo { while ( 1 ) { BSONElement ie = i.next(); BSONElement se = s.next(); - if ( ie.eoo() ) { - if ( !se.eoo() ) - return 0; + if ( ie.eoo() && !se.eoo() ) + return 0; + if ( ie.eoo() || se.eoo() ) return direction; - } + if ( strcmp( ie.fieldName(), se.fieldName() ) != 0 ) return 0; @@ -146,6 +146,11 @@ namespace mongo { set<string> queryFields; query.getFieldNames(queryFields); + if ( queryFields.size() == 0 ) { + DEV out() << "getIndexCursor fail " << ns << '\n'; + return auto_ptr<Cursor>(); + } + // regular query without order by for (int i = 0; i < d->nIndexes; i++ ) { BSONObj idxInfo = d->indexes[i].info.obj(); // { name:, ns:, key: } @@ -153,7 +158,12 @@ namespace mongo { set<string> keyFields; idxKey.getFieldNames(keyFields); - if ( keyFields == queryFields ) { + bool subset = true; + for( set<string>::iterator j = queryFields.begin(); subset && j != queryFields.end(); ++j ) + if ( keyFields.count( *j ) == 0 ) + subset = false; + + if ( subset ) { BSONObj q = query.extractFieldsUnDotted(idxKey); assert(q.objsize() != 0); // guard against a seg fault if details is 0 diff --git a/jstests/index7.js b/jstests/index7.js index 7bd46a82568..bfbe9c8e07f 100644 --- a/jstests/index7.js +++ b/jstests/index7.js @@ -42,12 +42,14 @@ f.drop(); f.ensureIndex( { a: 1, b: 1 } ); index( f.find().sort( { a: 1, b: 1 } ) ); index( f.find().sort( { a: -1, b: -1 } ) ); +index( f.find().sort( { a: 1 } ) ); +index( f.find().sort( { a: 1 } ).hint( { a: 1, b: 1 } ) ); noIndex( f.find().sort( { a: 1, b: -1 } ) ); noIndex( f.find().sort( { b: 1, a: 1 } ) ); noIndex( f.find() ); noIndex( f.find( { c: 1 } ) ); -noIndex( f.find( { a: 1 } ) ); // Once we enhance the query optimizer, this should get an index. +index( f.find( { a: 1 } ) ); index( f.find( { a: 1, b: 1 } ) ); index( f.find( { b: 1, a: 1 } ) ); |