diff --git a/db/btree.h b/db/btree.h index c3327c04eae..0dbcb067a6d 100644 --- a/db/btree.h +++ b/db/btree.h @@ -385,6 +385,7 @@ namespace mongo { } virtual bool modifiedKeys() const { return _multikey; } + virtual bool isMultiKey() const { return _multikey; } const _KeyNode& _currKeyNode() const { assert( !bucket.isNull() ); diff --git a/db/cursor.h b/db/cursor.h index bfad4fd6747..1b0d402c2d2 100644 --- a/db/cursor.h +++ b/db/cursor.h @@ -93,6 +93,8 @@ namespace mongo { */ virtual bool getsetdup(DiskLoc loc) = 0; + virtual bool isMultiKey() const = 0; + /** * return true if the keys in the index have been modified from the main doc * if you have { a : 1 , b : [ 1 , 2 ] } @@ -161,6 +163,7 @@ namespace mongo { } virtual bool tailable() { return tailable_; } virtual bool getsetdup(DiskLoc loc) { return false; } + virtual bool isMultiKey() const { return false; } virtual bool modifiedKeys() const { return false; } virtual bool supportGetMore() { return true; } virtual bool supportYields() { return true; } diff --git a/db/geo/2d.cpp b/db/geo/2d.cpp index 26574a2573c..6e9aac7c6ba 100644 --- a/db/geo/2d.cpp +++ b/db/geo/2d.cpp @@ -1066,6 +1066,7 @@ namespace mongo { virtual bool getsetdup(DiskLoc loc) { return false; } virtual bool modifiedKeys() const { return true; } + virtual bool isMultiKey() const { return false; } diff --git a/db/query.cpp b/db/query.cpp index 0f96ef57321..7de5aa4f089 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -569,6 +569,7 @@ namespace mongo { *_b << "nYields" << nYields; *_b << "nChunkSkips" << nChunkSkips; + *_b << "isMultiKey" << c->isMultiKey(); *_b << "indexBounds" << c->prettyIndexBounds(); diff --git a/db/queryoptimizer.cpp b/db/queryoptimizer.cpp index 5c9953a4334..ce5d660f98b 100644 --- a/db/queryoptimizer.cpp +++ b/db/queryoptimizer.cpp @@ -273,6 +273,14 @@ namespace mongo { return false; } + bool QueryPlanSet::hasMultiKey() const { + for( PlanSet::const_iterator i = _plans.begin(); i != _plans.end(); ++i ) + if ( (*i)->isMultiKey() ) + return true; + return false; + } + + void QueryPlanSet::addHint( IndexDetails &id ) { if ( !_min.isEmpty() || !_max.isEmpty() ) { string errmsg; diff --git a/db/queryoptimizer.h b/db/queryoptimizer.h index 13be9edf947..fb92e00933f 100644 --- a/db/queryoptimizer.h +++ b/db/queryoptimizer.h @@ -206,6 +206,7 @@ namespace mongo { const FieldRangeSet &fbs() const { return *_fbs; } const FieldRangeSet &originalFrs() const { return *_originalFrs; } bool modifiedKeys() const; + bool hasMultiKey() const; private: void addOtherPlans( bool checkFirst ); @@ -300,6 +301,8 @@ namespace mongo { void setBestGuessOnly() { _bestGuessOnly = true; } void mayYield( bool val ) { _mayYield = val; } bool modifiedKeys() const { return _currentQps->modifiedKeys(); } + bool hasMultiKey() const { return _currentQps->hasMultiKey(); } + private: void assertNotOr() const { massert( 13266, "not implemented for $or query", !_or ); @@ -384,6 +387,8 @@ namespace mongo { virtual bool modifiedKeys() const { return _mps->modifiedKeys(); } + virtual bool isMultiKey() const { return _mps->hasMultiKey(); } + virtual CoveredIndexMatcher *matcher() const { return _matcher.get(); } // return -1 if we're a getmore handoff virtual long long nscanned() { return _nscanned >= 0 ? _nscanned + _c->nscanned() : _nscanned; }