Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

handle multiple geo indexes with $near SERVER-686

  • Loading branch information...
commit 0a8e1f91c83bce14480e9cda00a1f630a5c64e93 1 parent 581980e
@erh erh authored
View
2  db/index.h
@@ -30,7 +30,7 @@ namespace mongo {
class IndexPlugin;
class IndexDetails;
- enum IndexSuitability { USELESS , HELPFUL , OPTIMAL };
+ enum IndexSuitability { USELESS = 0 , HELPFUL = 1 , OPTIMAL = 2 };
/**
* this represents an instance of a index plugin
View
9 db/index_geo2d.cpp
@@ -28,6 +28,9 @@
#include "matcher.h"
namespace mongo {
+
+#define GEODEBUG(x) cout << x << endl;
+ //#define GEODEBUG(x)
const string GEO2DNAME = "2d";
@@ -733,7 +736,7 @@ namespace mongo {
_lookedAt++;
double d = _g->distance( _near , node.key.firstElement() );
- //cout << "\t" << node.recordLoc.obj() << "\t" << d << endl;
+ GEODEBUG( "\t" << node.recordLoc.obj() << "\t" << d );
if ( _points.size() >= _max && d > farthest() )
return;
@@ -874,7 +877,7 @@ namespace mongo {
if ( ! _prefix.constrains() )
break;
_prefix = _prefix.up();
- //cout << _prefix << "\t" << _found << "\t" << endl;
+ GEODEBUG( _prefix << "\t" << _found );
}
}
@@ -1017,7 +1020,7 @@ namespace mongo {
e = e.embeddedObject().firstElement();
n = _tohash( e );
}
- uassert( 13042 , "no geo field" , n.constrains() );
+ uassert( 13042 , (string)"missing geo field (" + _geo + ") in : " + query.toString() , n.constrains() );
shared_ptr<GeoSearch> s( new GeoSearch( this , n , numWanted , query ) );
s->exec();
View
5 db/queryoptimizer.cpp
@@ -327,7 +327,8 @@ namespace mongo {
while( i.more() ) {
int j = i.pos();
IndexDetails& ii = i.next();
- if ( ii.getSpec().getTypeName() == special ){
+ const IndexSpec& spec = ii.getSpec();
+ if ( spec.getTypeName() == special && spec.suitability( query_ , order_ ) ){
usingPrerecordedPlan_ = true;
mayRecordPlan_ = true;
plans_.push_back( PlanPtr( new QueryPlan( d , j , fbs_ , order_ ,
@@ -335,7 +336,7 @@ namespace mongo {
return;
}
}
- uassert( 13038 , (string)"can't find special index: " + special , 0 );
+ uassert( 13038 , (string)"can't find special index: " + special + " for: " + query_.toString() , 0 );
}
if ( honorRecordedPlan_ ) {
View
7 jstests/geo2.js
@@ -23,17 +23,12 @@ assert.lt( fast.stats.nscanned * 10 , slow.stats.nscanned , "A1" + v );
assert.lt( fast.stats.objectsLoaded , slow.stats.objectsLoaded , "A2" + v );
assert.eq( fast.stats.avgDistance , slow.stats.avgDistance , "A3" + v );
-function dis( a , b ){
- return Math.sqrt( Math.pow( b[0] - a[0] , 2 ) +
- Math.pow( b[1] - a[1] , 2 ) );
-}
-
function a( cur ){
var total = 0;
var outof = 0;
while ( cur.hasNext() ){
var o = cur.next();
- total += dis( [ 50 , 50 ] , o.loc );
+ total += Geo.distance( [ 50 , 50 ] , o.loc );
outof++;
}
return total/outof;
View
28 jstests/geo9.js
@@ -0,0 +1,28 @@
+
+t = db.geo9
+t.drop();
+
+t.save( { _id : 1 , a : [ 10 , 10 ] , b : [ 50 , 50 ] } )
+t.save( { _id : 2 , a : [ 11 , 11 ] , b : [ 51 , 52 ] } )
+t.save( { _id : 3 , a : [ 12 , 12 ] , b : [ 52 , 52 ] } )
+
+t.save( { _id : 4 , a : [ 50 , 50 ] , b : [ 10 , 10 ] } )
+t.save( { _id : 5 , a : [ 51 , 51 ] , b : [ 11 , 11 ] } )
+t.save( { _id : 6 , a : [ 52 , 52 ] , b : [ 12 , 12 ] } )
+
+t.ensureIndex( { a : "2d" } )
+t.ensureIndex( { b : "2d" } )
+
+function check( field ){
+ var q = {}
+ q[field] = { $near : [ 11 , 11 ] }
+ arr = t.find( q ).limit(3).map(
+ function(z){
+ return Geo.distance( [ 11 , 11 ] , z[field] );
+ }
+ );
+ assert.eq( 2 * Math.sqrt( 2 ) , Array.sum( arr ) , "test " + field );
+}
+
+check( "a" )
+check( "b" )
View
25 shell/utils.js
@@ -924,3 +924,28 @@ killWithUris = function( uris ) {
}
}
}
+
+Geo = {};
+Geo.distance = function( a , b ){
+ var ax = null;
+ var ay = null;
+ var bx = null;
+ var by = null;
+
+ for ( var key in a ){
+ if ( ax == null )
+ ax = a[key];
+ else if ( ay == null )
+ ay = a[key];
+ }
+
+ for ( var key in b ){
+ if ( bx == null )
+ bx = b[key];
+ else if ( by == null )
+ by = b[key];
+ }
+
+ return Math.sqrt( Math.pow( by - ay , 2 ) +
+ Math.pow( bx - ax , 2 ) );
+}
Please sign in to comment.
Something went wrong with that request. Please try again.