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 queryFields; query.getFieldNames(queryFields); + if ( queryFields.size() == 0 ) { + DEV out() << "getIndexCursor fail " << ns << '\n'; + return auto_ptr(); + } + // 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 keyFields; idxKey.getFieldNames(keyFields); - if ( keyFields == queryFields ) { + bool subset = true; + for( set::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 } ) );