summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2009-02-11 15:37:51 -0500
committerAaron <aaron@10gen.com>2009-02-11 15:37:51 -0500
commitc326d4a5086dfb2610c960cdedfe8735adc68376 (patch)
tree882af336ccc2b154a7bf5862ad0df3a13bc9f554
parent878cffc529ec5987deacfc15b9dd919e79ae8248 (diff)
downloadmongo-c326d4a5086dfb2610c960cdedfe8735adc68376.tar.gz
Can pick index with more key specificity than required by sort / find spec
-rw-r--r--db/jsobj.cpp12
-rw-r--r--db/jsobj.h3
-rw-r--r--db/query.cpp20
-rw-r--r--jstests/index7.js4
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 } ) );