0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

if key is in index, use it for distinct SERVER-1673

This commit is contained in:
Eliot Horowitz 2010-11-14 01:42:36 -05:00
parent 8450572c05
commit 2c9fe6b427
4 changed files with 56 additions and 15 deletions

View File

@ -258,8 +258,7 @@ namespace mongo {
_cursorid = allocCursorId_inlock();
clientCursorsById.insert( make_pair(_cursorid, this) );
#if 0
{
if ( ! _c->modifiedKeys() ) {
// store index information so we can decide if we can
// get something out of the index key rather than full object
@ -274,7 +273,7 @@ namespace mongo {
x++;
}
}
#endif
}
@ -292,6 +291,24 @@ namespace mongo {
}
}
bool ClientCursor::getFieldsDotted( const string& name, BSONElementSet &ret ) {
map<string,int>::const_iterator i = _indexedFields.find( name );
if ( i == _indexedFields.end() ){
current().getFieldsDotted( name , ret );
return false;
}
int x = i->second;
BSONObjIterator it( currKey() );
while ( x && it.more() )
it.next();
assert( x == 0 );
ret.insert( it.next() );
return true;
}
/* call when cursor's location changes so that we can update the
cursorsbylocation map. if you are locked and internally iterating, only
need to call when you are ready to "unlock".

View File

@ -221,7 +221,15 @@ namespace mongo {
bool advance(){ return _c->advance(); }
BSONObj current() { return _c->current(); }
DiskLoc currLoc() { return _c->currLoc(); }
BSONObj currKey() { return _c->currKey(); }
BSONObj currKey() const { return _c->currKey(); }
/**
* same as BSONObj::getFieldsDotted
* if it can be retrieved from key, it is
* @return if this was retrieved from key
*/
bool getFieldsDotted( const string& name, BSONElementSet &ret );
bool currentIsDup() { return _c->getsetdup( _c->currLoc() ); }

View File

@ -47,8 +47,9 @@ namespace mongo {
BSONArrayBuilder arr( bb );
BSONElementSet values;
long long nscanned = 0;
long long n = 0;
long long nscanned = 0; // locations looked at
long long nscannedObjects = 0; // full objects looked at
long long n = 0; // matches
MatchDetails md;
shared_ptr<Cursor> cursor = bestGuessCursor(ns.c_str() , query , BSONObj() );
@ -59,11 +60,10 @@ namespace mongo {
bool loadedObject = false;
if ( !cursor->matcher() || cursor->matcher()->matchesCurrent( cursor.get() , &md ) ){
loadedObject = true;
BSONObj o = cursor->current();
n++;
BSONElementSet temp;
o.getFieldsDotted( key, temp );
loadedObject = ! cc->getFieldsDotted( key , temp );
for ( BSONElementSet::iterator i=temp.begin(); i!=temp.end(); ++i ){
BSONElement e = *i;
@ -82,7 +82,7 @@ namespace mongo {
}
if ( loadedObject || md.loadedObject )
n++;
nscannedObjects++;
cursor->advance();
@ -100,6 +100,7 @@ namespace mongo {
BSONObjBuilder b;
b.appendNumber( "n" , n );
b.appendNumber( "nscanned" , nscanned );
b.appendNumber( "nscannedObjects" , nscannedObjects );
result.append( "stats" , b.obj() );
}

View File

@ -2,8 +2,8 @@
t = db.distinct_index1
t.drop();
function r(){
return Math.floor( Math.random() * 10 );
function r( x ){
return Math.floor( Math.sqrt( x * 123123 ) ) % 10;
}
function d( k , q ){
@ -11,17 +11,32 @@ function d( k , q ){
}
for ( i=0; i<1000; i++ ){
o = { a : r() , b : r() };
o = { a : r(i*5) , b : r(i) };
t.insert( o );
}
x = d( "a" );
assert.eq( 1000 , x.stats.n , "A1" )
assert.eq( 1000 , x.stats.nscanned , "A2" )
assert.eq( 1000 , x.stats.nscannedObjects , "A3" )
x = d( "a" , { a : { $gt : 5 } } );
assert.eq( 1000 , x.stats.n , "A1" )
assert.eq( 1000 , x.stats.nscanned , "A2" )
assert.eq( 398 , x.stats.n , "B1" )
assert.eq( 1000 , x.stats.nscanned , "B2" )
assert.eq( 1000 , x.stats.nscannedObjects , "B3" )
t.ensureIndex( { a : 1 } )
x = d( "a" );
assert.eq( 1000 , x.stats.n , "C1" )
assert.eq( 1000 , x.stats.nscanned , "C2" )
assert.eq( 1000 , x.stats.nscannedObjects , "C3" )
x = d( "a" , { a : { $gt : 5 } } );
assert.eq( 398 , x.stats.n , "D1" )
assert.eq( 398 , x.stats.nscanned , "D2" )
assert.eq( 0 , x.stats.nscannedObjects , "D3" )