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:
parent
8450572c05
commit
2c9fe6b427
@ -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".
|
||||
|
@ -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() ); }
|
||||
|
||||
|
@ -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() );
|
||||
}
|
||||
|
||||
|
@ -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" )
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user