Files
mongo/jstests/core/geo_borders.js
Greg Studer 3c5246b1fb SERVER-9986 refactor near search for 2D and S2
Adds progressive search functionality for $geoNear operations,
allowing better integration with other cursors.
2014-07-09 07:36:48 -04:00

168 lines
6.4 KiB
JavaScript

t = db.borders
t.drop()
epsilon = 0.0001;
// For these tests, *required* that step ends exactly on max
min = -1
max = 1
step = 1
numItems = 0;
for ( var x = min; x <= max; x += step ) {
for ( var y = min; y <= max; y += step ) {
t.insert( { loc : { x : x, y : y } } )
numItems++;
}
}
overallMin = -1
overallMax = 1
// Create a point index slightly smaller than the points we have
var res = t.ensureIndex({ loc: "2d" },
{ max: overallMax - epsilon / 2,
min: overallMin + epsilon / 2 });
assert.commandFailed(res);
// Create a point index only slightly bigger than the points we have
res = t.ensureIndex( { loc : "2d" }, { max : overallMax + epsilon, min : overallMin - epsilon } );
assert.commandWorked(res);
// ************
// Box Tests
// ************
// If the bounds are bigger than the box itself, just clip at the borders
assert.eq( numItems, t.find(
{ loc : { $within : { $box : [
[ overallMin - 2 * epsilon, overallMin - 2 * epsilon ],
[ overallMax + 2 * epsilon, overallMax + 2 * epsilon ] ] } } } ).count() );
// Check this works also for bounds where only a single dimension is off-bounds
assert.eq( numItems - 5, t.find(
{ loc : { $within : { $box : [
[ overallMin - 2 * epsilon, overallMin - 0.5 * epsilon ],
[ overallMax - epsilon, overallMax - epsilon ] ] } } } ).count() );
// Make sure we can get at least close to the bounds of the index
assert.eq( numItems, t.find(
{ loc : { $within : { $box : [
[ overallMin - epsilon / 2, overallMin - epsilon / 2 ],
[ overallMax + epsilon / 2, overallMax + epsilon / 2 ] ] } } } ).count() );
// Make sure we can get at least close to the bounds of the index
assert.eq( numItems, t.find(
{ loc : { $within : { $box : [
[ overallMax + epsilon / 2, overallMax + epsilon / 2 ],
[ overallMin - epsilon / 2, overallMin - epsilon / 2 ] ] } } } ).count() );
// Check that swapping min/max has good behavior
assert.eq( numItems, t.find(
{ loc : { $within : { $box : [
[ overallMax + epsilon / 2, overallMax + epsilon / 2 ],
[ overallMin - epsilon / 2, overallMin - epsilon / 2 ] ] } } } ).count() );
assert.eq( numItems, t.find(
{ loc : { $within : { $box : [
[ overallMax + epsilon / 2, overallMin - epsilon / 2 ],
[ overallMin - epsilon / 2, overallMax + epsilon / 2 ] ] } } } ).count() );
// **************
// Circle tests
// **************
center = ( overallMax + overallMin ) / 2
center = [ center, center ]
radius = overallMax
offCenter = [ center[0] + radius, center[1] + radius ]
onBounds = [ offCenter[0] + epsilon, offCenter[1] + epsilon ]
offBounds = [ onBounds[0] + epsilon, onBounds[1] + epsilon ]
onBoundsNeg = [ -onBounds[0], -onBounds[1] ]
// Make sure we can get all points when radius is exactly at full bounds
assert.lt( 0, t.find( { loc : { $within : { $center : [ center, radius + epsilon ] } } } ).count() );
// Make sure we can get points when radius is over full bounds
assert.lt( 0, t.find( { loc : { $within : { $center : [ center, radius + 2 * epsilon ] } } } ).count() );
// Make sure we can get points when radius is over full bounds, off-centered
assert.lt( 0, t.find( { loc : { $within : { $center : [ offCenter, radius + 2 * epsilon ] } } } ).count() );
// Make sure we get correct corner point when center is in bounds
// (x bounds wrap, so could get other corner)
cornerPt = t.findOne( { loc : { $within : { $center : [ offCenter, step / 2 ] } } } );
assert.eq( cornerPt.loc.y, overallMax )
// Make sure we get correct corner point when center is on bounds
// NOTE: Only valid points on MIN bounds
cornerPt = t
.findOne( { loc : { $within : { $center : [ onBoundsNeg, Math.sqrt( 2 * epsilon * epsilon ) + ( step / 2 ) ] } } } );
assert.eq( cornerPt.loc.y, overallMin )
// Make sure we can't get corner point when center is over bounds
// TODO: SERVER-5800 clean up wrapping rules for different CRS queries - not sure this is an error
/*
assert.throws(function(){
t.findOne( { loc : { $within : { $center : [ offBounds, Math.sqrt( 8 * epsilon * epsilon ) + ( step / 2 ) ] } } } );
});
*/
// Make sure we can't get corner point when center is on max bounds
// Broken - see SERVER-13581
//assert.throws(function(){
// t.findOne( { loc : { $within : { $center : [ onBounds, Math.sqrt( 8 * epsilon * epsilon ) + ( step / 2 ) ] } } } );
//});
// ***********
// Near tests
// ***********
// Make sure we can get all nearby points to point in range
assert.eq( overallMax, t.find( { loc : { $near : offCenter } } ).next().loc.y );
// Make sure we can get all nearby points to point on boundary
assert.eq( overallMin, t.find( { loc : { $near : onBoundsNeg } } ).next().loc.y );
// Make sure we can't get all nearby points to point over boundary
// TODO: SERVER-9986 clean up wrapping rules for different CRS queries - not sure this is an error
/*
assert.throws(function(){
t.findOne( { loc : { $near : offBounds } } );
});
*/
// Make sure we can't get all nearby points to point on max boundary
//Broken - see SERVER-13581
//assert.throws(function(){
// t.findOne( { loc : { $near : onBoundsNeg } } );
//});
// Make sure we can get all nearby points within one step (4 points in top
// corner)
assert.eq( 4, t.find( { loc : { $near : offCenter, $maxDistance : step * 1.9 } } ).count() );
// **************
// Command Tests
// **************
// Make sure we can get all nearby points to point in range
assert.eq( overallMax, db.runCommand( { geoNear : "borders", near : offCenter } ).results[0].obj.loc.y );
// Make sure we can get all nearby points to point on boundary
assert.eq( overallMin, db.runCommand( { geoNear : "borders", near : onBoundsNeg } ).results[0].obj.loc.y );
// Make sure we can't get all nearby points to point over boundary
//TODO: SERVER-9986 clean up wrapping rules for different CRS queries - not sure this is an error
/*
assert.commandFailed( db.runCommand( { geoNear : "borders", near : offBounds } ));
*/
// Make sure we can't get all nearby points to point on max boundary
assert.commandWorked( db.runCommand( { geoNear : "borders", near : onBounds } ));
// Make sure we can get all nearby points within one step (4 points in top
// corner)
assert.eq( 4, db.runCommand( { geoNear : "borders", near : offCenter, maxDistance : step * 1.5 } ).results.length );