summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2010-11-16 16:11:43 -0500
committerEliot Horowitz <eliot@10gen.com>2010-11-16 16:11:43 -0500
commit2603a9632c21f9e56e780f57b15313ed9d8810ff (patch)
treebd576ef14dab3a10f05a72edeef4837e1b448d20 /db
parent778d26e20c75ade65dc8b3a57d60d61651947df6 (diff)
downloadmongo-2603a9632c21f9e56e780f57b15313ed9d8810ff.tar.gz
use data from indexes if possivle SERVER-192
Diffstat (limited to 'db')
-rw-r--r--db/clientcursor.h7
-rw-r--r--db/query.cpp41
2 files changed, 39 insertions, 9 deletions
diff --git a/db/clientcursor.h b/db/clientcursor.h
index 98cbdd8f7c2..97490b3b1fa 100644
--- a/db/clientcursor.h
+++ b/db/clientcursor.h
@@ -218,6 +218,9 @@ namespace mongo {
void setPos( int n ) { _pos = n; } // TODO : this is bad too
BSONObj indexKeyPattern() { return _c->indexKeyPattern(); }
+ bool modifiedKeys() const { return _c->modifiedKeys(); }
+ bool isMultiKey() const { return _c->isMultiKey(); }
+
bool ok() { return _c->ok(); }
bool advance(){ return _c->advance(); }
BSONObj current() { return _c->current(); }
@@ -354,8 +357,8 @@ namespace mongo {
ElapsedTracker _yieldSometimesTracker;
public:
- shared_ptr< ParsedQuery > pq;
- shared_ptr< Projection > fields; // which fields query wants returned
+ shared_ptr<ParsedQuery> pq;
+ shared_ptr<Projection> fields; // which fields query wants returned
Message originalMessage; // this is effectively an auto ptr for data the matcher points to
diff --git a/db/query.cpp b/db/query.cpp
index 7de5aa4f089..09afa14a4b2 100644
--- a/db/query.cpp
+++ b/db/query.cpp
@@ -290,7 +290,7 @@ namespace mongo {
int resultFlags = ResultFlag_AwaitCapable;
int start = 0;
int n = 0;
-
+
if ( !cc ) {
log() << "getMore: cursorid not found " << ns << " " << cursorid << endl;
cursorid = 0;
@@ -312,6 +312,10 @@ namespace mongo {
c->checkLocation();
DiskLoc last;
+ scoped_ptr<Projection::KeyOnly> keyFieldsOnly;
+ if ( cc->modifiedKeys() == false && cc->isMultiKey() == false && cc->fields )
+ keyFieldsOnly.reset( cc->fields->checkKey( cc->indexKeyPattern() ) );
+
while ( 1 ) {
if ( !c->ok() ) {
if ( c->tailable() ) {
@@ -350,11 +354,17 @@ namespace mongo {
}
else {
last = c->currLoc();
- BSONObj js = c->current();
-
- // show disk loc should be part of the main query, not in an $or clause, so this should be ok
- fillQueryResultFromObj(b, cc->fields.get(), js, ( cc->pq.get() && cc->pq->showDiskLoc() ? &last : 0));
n++;
+
+ if ( keyFieldsOnly ){
+ fillQueryResultFromObj(b, 0, keyFieldsOnly->hydrate( c->currKey() ) );
+ }
+ else {
+ BSONObj js = c->current();
+ // show disk loc should be part of the main query, not in an $or clause, so this should be ok
+ fillQueryResultFromObj(b, cc->fields.get(), js, ( cc->pq.get() && cc->pq->showDiskLoc() ? &last : 0));
+ }
+
if ( ( ntoreturn && n >= ntoreturn ) || b.len() > MaxBytesToReturnToClientAtOnce ){
c->advance();
cc->incPos( n );
@@ -547,7 +557,8 @@ namespace mongo {
b << "cursor" << c->toString() << "indexBounds" << c->prettyIndexBounds();
b.done();
}
- void noteScan( Cursor *c, long long nscanned, long long nscannedObjects, int n, bool scanAndOrder, int millis, bool hint, int nYields , int nChunkSkips ) {
+ void noteScan( Cursor *c, long long nscanned, long long nscannedObjects, int n, bool scanAndOrder,
+ int millis, bool hint, int nYields , int nChunkSkips , bool indexOnly ) {
if ( _i == 1 ) {
_c.reset( new BSONArrayBuilder() );
*_c << _b->obj();
@@ -570,6 +581,7 @@ namespace mongo {
*_b << "nYields" << nYields;
*_b << "nChunkSkips" << nChunkSkips;
*_b << "isMultiKey" << c->isMultiKey();
+ *_b << "indexOnly" << indexOnly;
*_b << "indexBounds" << c->prettyIndexBounds();
@@ -640,6 +652,15 @@ namespace mongo {
} else {
_c = qp().newCursor( DiskLoc() , _pq.getNumToReturn() + _pq.getSkip() );
_capped = _c->capped();
+
+ cout << "ELIOT : " << _pq.getFields() << endl;
+
+ // setup check for if we can only use index to extract
+ if ( _c->modifiedKeys() == false && _c->isMultiKey() == false && _pq.getFields() ){
+ cout << "\t YO" << endl;
+ _keyFieldsOnly.reset( _pq.getFields()->checkKey( _c->indexKeyPattern() ) );
+ cout << "\t " << _keyFieldsOnly.get() << endl;
+ }
}
if ( qp().scanAndOrderRequired() ) {
@@ -763,6 +784,9 @@ namespace mongo {
bb.appendKeys( _c->indexKeyPattern() , _c->currKey() );
bb.done();
}
+ else if ( _keyFieldsOnly ){
+ fillQueryResultFromObj( _buf , 0 , _keyFieldsOnly->hydrate( _c->currKey() ) );
+ }
else {
BSONObj js = _c->current();
assert( js.isValid() );
@@ -824,7 +848,9 @@ namespace mongo {
}
if ( _pq.isExplain() ) {
- _eb.noteScan( _c.get(), _nscanned, _nscannedObjects, _n, scanAndOrderRequired(), _curop.elapsedMillis(), useHints && !_pq.getHint().eoo(), _nYields , _nChunkSkips);
+ _eb.noteScan( _c.get(), _nscanned, _nscannedObjects, _n, scanAndOrderRequired(),
+ _curop.elapsedMillis(), useHints && !_pq.getHint().eoo(), _nYields ,
+ _nChunkSkips, _keyFieldsOnly.get() > 0 );
}
else {
if ( _buf.len() ) {
@@ -883,6 +909,7 @@ namespace mongo {
private:
BufBuilder _buf;
const ParsedQuery& _pq;
+ scoped_ptr<Projection::KeyOnly> _keyFieldsOnly;
long long _ntoskip;
long long _nscanned;