mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
checkpoint on $near op
This commit is contained in:
parent
3d2b4f8ad4
commit
f08ba724c3
@ -46,6 +46,8 @@ namespace mongo {
|
||||
|
||||
const IndexPlugin * getPlugin() const { return _plugin; }
|
||||
|
||||
virtual auto_ptr<Cursor> newCursor( const BSONObj& query , const BSONObj& order ) const = 0;
|
||||
|
||||
virtual BSONObj fixKey( const BSONObj& in ) { return in; }
|
||||
|
||||
protected:
|
||||
|
@ -327,6 +327,12 @@ namespace mongo {
|
||||
return _spec->getDetails();
|
||||
}
|
||||
|
||||
virtual auto_ptr<Cursor> newCursor( const BSONObj& query , const BSONObj& order ) const {
|
||||
auto_ptr<Cursor> c;
|
||||
assert(0);
|
||||
return c;
|
||||
}
|
||||
|
||||
const IndexSpec* _spec;
|
||||
string _geo;
|
||||
vector<string> _other;
|
||||
|
@ -436,8 +436,12 @@ namespace mongo {
|
||||
else if ( fn[3] == 'e' && fn[4] == 0 ) return BSONObj::LTE;
|
||||
}
|
||||
}
|
||||
else if ( fn[1] == 'n' && fn[2] == 'e' && fn[3] == 0)
|
||||
return BSONObj::NE;
|
||||
else if ( fn[1] == 'n' && fn[2] == 'e' ){
|
||||
if ( fn[3] == 0 )
|
||||
return BSONObj::NE;
|
||||
if ( fn[3] == 'a' && fn[4] == 'r' && fn[5] == 0 )
|
||||
return BSONObj::opNEAR;
|
||||
}
|
||||
else if ( fn[1] == 'm' && fn[2] == 'o' && fn[3] == 'd' && fn[4] == 0 )
|
||||
return BSONObj::opMOD;
|
||||
else if ( fn[1] == 't' && fn[2] == 'y' && fn[3] == 'p' && fn[4] == 'e' && fn[5] == 0 )
|
||||
|
@ -993,7 +993,8 @@ namespace mongo {
|
||||
opTYPE = 0x0F,
|
||||
opREGEX = 0x10,
|
||||
opOPTIONS = 0x11,
|
||||
opELEM_MATCH = 0x12
|
||||
opELEM_MATCH = 0x12,
|
||||
opNEAR = 0x13
|
||||
};
|
||||
};
|
||||
ostream& operator<<( ostream &s, const BSONObj &o );
|
||||
|
@ -248,6 +248,8 @@ namespace mongo {
|
||||
flags = fe.valuestrsafe();
|
||||
break;
|
||||
}
|
||||
case BSONObj::opNEAR:
|
||||
break;
|
||||
default:
|
||||
uassert( 10069 , (string)"BUG - can't operator for: " + fn , 0 );
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace mongo {
|
||||
|
||||
QueryPlan::QueryPlan(
|
||||
NamespaceDetails *_d, int _idxNo,
|
||||
const FieldRangeSet &fbs, const BSONObj &order, const BSONObj &startKey, const BSONObj &endKey ) :
|
||||
const FieldRangeSet &fbs, const BSONObj &order, const BSONObj &startKey, const BSONObj &endKey , string special ) :
|
||||
d(_d), idxNo(_idxNo),
|
||||
fbs_( fbs ),
|
||||
order_( order ),
|
||||
@ -73,7 +73,8 @@ namespace mongo {
|
||||
exactKeyMatch_( false ),
|
||||
direction_( 0 ),
|
||||
endKeyInclusive_( endKey.isEmpty() ),
|
||||
unhelpful_( false ) {
|
||||
unhelpful_( false ),
|
||||
_special( special ){
|
||||
|
||||
if ( !fbs_.matchPossible() ) {
|
||||
unhelpful_ = true;
|
||||
@ -90,6 +91,12 @@ namespace mongo {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( _special.size() ){
|
||||
optimal_ = true;
|
||||
scanAndOrderRequired_ = false; // TODO: maybe part of key spec?
|
||||
return;
|
||||
}
|
||||
|
||||
BSONObj idxKey = index_->keyPattern();
|
||||
BSONObjIterator o( order );
|
||||
BSONObjIterator k( idxKey );
|
||||
@ -179,6 +186,13 @@ namespace mongo {
|
||||
}
|
||||
|
||||
auto_ptr< Cursor > QueryPlan::newCursor( const DiskLoc &startLoc ) const {
|
||||
|
||||
if ( _special.size() ){
|
||||
IndexType * type = index_->getSpec().getType();
|
||||
massert( 13040 , (string)"no type for special: " + _special , type );
|
||||
return type->newCursor( fbs_.query() , order_ );
|
||||
}
|
||||
|
||||
if ( !fbs_.matchPossible() ){
|
||||
if ( fbs_.nNontrivialRanges() )
|
||||
checkTableScanAllowed( fbs_.ns() );
|
||||
@ -322,6 +336,23 @@ namespace mongo {
|
||||
}
|
||||
}
|
||||
|
||||
if ( fbs_.getSpecial().size() ){
|
||||
string special = fbs_.getSpecial();
|
||||
NamespaceDetails::IndexIterator i = d->ii();
|
||||
while( i.more() ) {
|
||||
int j = i.pos();
|
||||
IndexDetails& ii = i.next();
|
||||
if ( ii.getSpec().getTypeName() == special ){
|
||||
usingPrerecordedPlan_ = true;
|
||||
mayRecordPlan_ = true;
|
||||
plans_.push_back( PlanPtr( new QueryPlan( d , j , fbs_ , order_ ,
|
||||
BSONObj() , BSONObj() , special ) ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
uassert( 13038 , (string)"can't find special index: " + special , 0 );
|
||||
}
|
||||
|
||||
if ( honorRecordedPlan_ ) {
|
||||
boostlock lk(NamespaceDetailsTransient::_qcMutex);
|
||||
NamespaceDetailsTransient& nsd = NamespaceDetailsTransient::get_inlock( ns );
|
||||
|
@ -32,7 +32,8 @@ namespace mongo {
|
||||
const FieldRangeSet &fbs,
|
||||
const BSONObj &order,
|
||||
const BSONObj &startKey = BSONObj(),
|
||||
const BSONObj &endKey = BSONObj() );
|
||||
const BSONObj &endKey = BSONObj() ,
|
||||
string special="" );
|
||||
|
||||
/* If true, no other index can do better. */
|
||||
bool optimal() const { return optimal_; }
|
||||
@ -70,6 +71,7 @@ namespace mongo {
|
||||
BoundList indexBounds_;
|
||||
bool endKeyInclusive_;
|
||||
bool unhelpful_;
|
||||
string _special;
|
||||
};
|
||||
|
||||
// Inherit from this interface to implement a new query operation.
|
||||
|
@ -253,6 +253,9 @@ namespace mongo {
|
||||
log() << "warning: shouldn't get here?" << endl;
|
||||
break;
|
||||
}
|
||||
case BSONObj::opNEAR:
|
||||
_special = "2d";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -312,6 +315,8 @@ namespace mongo {
|
||||
intervals_ = newIntervals;
|
||||
for( vector< BSONObj >::const_iterator i = other.objData_.begin(); i != other.objData_.end(); ++i )
|
||||
objData_.push_back( *i );
|
||||
if ( _special.size() == 0 && other._special.size() )
|
||||
_special = other._special;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -325,6 +330,17 @@ namespace mongo {
|
||||
return o;
|
||||
}
|
||||
|
||||
string FieldRangeSet::getSpecial() const {
|
||||
string s = "";
|
||||
for ( map<string,FieldRange>::iterator i=ranges_.begin(); i!=ranges_.end(); i++ ){
|
||||
if ( i->second.getSpecial().size() == 0 )
|
||||
continue;
|
||||
uassert( 13033 , "can't have 2 special fields" , s.size() == 0 );
|
||||
s = i->second.getSpecial();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void FieldRangeSet::processOpElement( const char *fieldName, const BSONElement &f, bool isNot, bool optimize ) {
|
||||
int op2 = f.getGtLtOp();
|
||||
if ( op2 == BSONObj::opELEM_MATCH ) {
|
||||
@ -389,7 +405,7 @@ namespace mongo {
|
||||
processOpElement( e.fieldName(), f, true, optimize );
|
||||
break;
|
||||
default:
|
||||
uassert( 13033, "invalid use of $not", false );
|
||||
uassert( 13041, "invalid use of $not", false );
|
||||
}
|
||||
} else {
|
||||
processOpElement( e.fieldName(), f, false, optimize );
|
||||
|
@ -69,11 +69,14 @@ namespace mongo {
|
||||
}
|
||||
bool empty() const { return intervals_.empty(); }
|
||||
const vector< FieldInterval > &intervals() const { return intervals_; }
|
||||
string getSpecial() const { return _special; }
|
||||
|
||||
private:
|
||||
BSONObj addObj( const BSONObj &o );
|
||||
string simpleRegexEnd( string regex );
|
||||
vector< FieldInterval > intervals_;
|
||||
vector< BSONObj > objData_;
|
||||
string _special;
|
||||
};
|
||||
|
||||
// implements query pattern matching, used to determine if a query is
|
||||
@ -171,6 +174,7 @@ namespace mongo {
|
||||
}
|
||||
QueryPattern pattern( const BSONObj &sort = BSONObj() ) const;
|
||||
BoundList indexBounds( const BSONObj &keyPattern, int direction ) const;
|
||||
string getSpecial() const;
|
||||
private:
|
||||
void processOpElement( const char *fieldName, const BSONElement &f, bool isNot, bool optimize );
|
||||
static FieldRange *trivialRange_;
|
||||
|
@ -34,3 +34,6 @@ printjson( slow.stats )
|
||||
slow.results.forEach( p )
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//t.find( { loc : { $near : [ 50 , 50 ] } } ).itcount();
|
||||
|
Loading…
Reference in New Issue
Block a user