Geospatial and MongoDB
MongoDB Geospatial Features Agenda Query Examples Optimizations 2
Norberto Leite Developer Advocate Curriculum Engineer Twitter: @nleite norberto@mongodb.com 3
The Basics
[Longitude, Latitude]
Quiz Time! Which of these shapes is the must similar with Planet Earth?
Stripped version of Earth: Geoid http://www.ngs.noaa.gov/GEOID/ 7
Surface Types Flat Spherical 2d Indexes 2dsphere Indexes 8
2D Indexes var var place place = = { Defined by [lon,lat] arrays type: : "building" "building", name: : "AW1 - Building" "AW1 - Building" location: : [4.380717873573303 4.380717873573303,50.81219570880462 50.81219570880462] } var checkin var checkin = = { type: : "checkin checkin", Or use an embedded document message: : "this place is awesome!" "this place is awesome!" location: : { lng: : 4.348099529743194 4.348099529743194, lat: : 50.850980167854615 50.850980167854615 } } 9
2D Indexes //index creation db.col.createIndex .col.createIndex( { ( {'location' 'location': : '2d' '2d'}) }) db.col.createIndex .col.createIndex( { ( {'location' 'location': : '2d' '2d'}, { }, {'sparse' 'sparse': : true true}) }) 10
Spherical Surface var var place place = = { Defined by a type: : "building" "building", subdocument – GeoJSON Requires a type name: : "AW1" "AW1", location: : { //Line, MultiLine, Polygon, MultiPolygon, GeometryCollection type: : "Point" "Point", coordinates: : [4.380717873573303 4.380717873573303,50.81219570880462 50.81219570880462] } } Coordinates array 11
Spherical Surface var var place place = = { type: : "building" "building", name: : "AW1" "AW1", location: : { type: : "Polygon" "Polygon", coordinates: : [ [ [ 4.380406737327576 4.380406737327576, 50.812253331704625 50.812253331704625 ], ], [ 4.380889534950256 4.380889534950256, 50.81239569385869 50.81239569385869 ], ], [ 4.381093382835388 4.381093382835388, 50.812134696244804 50.812134696244804 ], ], [ 4.380605220794678 4.380605220794678, 50.81198894369594 50.81198894369594 ], ], [ 4.380406737327576 4.380406737327576, 50.812253331704625 50.812253331704625 ] ] http://geojson.org/ ] } }
2dsphere Indexes //index creation db.collection.createIndex .collection.createIndex( { location ( { location : : "2dsphere" "2dsphere" } ) } ) //compound with more than 2 members db.collection.createIndex .collection.createIndex( { location ( { location : : "2dsphere" "2dsphere", name , name: : 1, type , type: : 1 1 } ) } )
2d vs 2dsphere 2d index 2dsphere Legacy Spatial Support Coordinates Pair GeoJson Format Manual Earth-like geometry WGS84 Datum calculations Single extra field for compound Multiple fields indexes 14
Indexation
Points to Index Keys db.places.insert .places.insert({ ({ name: : "Starbucks" "Starbucks" loc: : { type: : "Point" "Point", coordinates: : [1.3 1.3,45 45] } }) }) db.places.createIndex .places.createIndex({ ({loc loc: : "2dsphere" "2dsphere"}) }) How does MongoDB generate index keys?
Points to Index Keys Project spherical point to bounding cube Each face is a Quadtree
Points to Index Keys Face 5 3 2 ... 0 1 Key 5F 5F1 5F12 5F120 Every cm 2 can be represented with 30 levels
S2 Library 19
Points to Index Keys Key 5F1 5F1 20 A key is a prefix of another iff it is a parent cell
Query Examples
Geospatial operators $geoWithin $geoIntersects $near/$nearSphere 22
$geoWithin 23
$geoWithin { location { location: : { { $geoWithin: : { $geometry : : { 'type': : "Polygon" "Polygon", 'coordinates': : [ [ [ [ -73.975181 73.975181, , 40.758494 40.758494 ], ], [ [ -73.973336 73.973336, , 40.760965 40.760965 ], ], [ [ -73.974924 73.974924, , 40.761663 40.761663 ], ], [ [ -73.976748 73.976748, , 40.759160 40.759160 ], ], [ [ -73.975181 73.975181, , 40.758494 40.758494 ] ] ] }}}} }}}} 24
$geoIntersects 25
$geoIntersects db.coll.find db.coll.find({ location: { ({ location: { $geoIntersects: : { $geometry: : { { "type" "type": : "LineString LineString", "coordinates": : [ [-73.979543 73.979543, , 40.761132 40.761132], ], [-73.974715 73.974715, , 40.759127 40.759127], ], [-73.973363 73.973363, , 40.760969 40.760969], ], [-73.970059 73.970059, , 40.759600 40.759600] ] } } } ) } } ) 26
$near Stage 1 Stage 2 Stage 3 27
Polygons
Coordinates System 90 135 180 -180 -120 -45 -10 10 45 90
Define a polygon by specifying 4 points 4 3 1 2 But what’s the inside of the polygon?
Convention for deciding “inside”: Winding Order + Right Hand Rule 4 3 1 2
Posi)ve = Inside of Polygon
But how does MongoDB pick the inside of the Polygon? 2 3 1 4
MongoDB 2.6 behavior 2 3 1 4
Small Areas Polygon 35
Polygon var var polygon polygon = = { "type": : "Polygon" "Polygon", "coordinates" : : [ [ [ [ -73.969581 73.969581, , 40.760331 40.760331 ], ], [ [ -73.974487 73.974487, , 40.762245 40.762245 ], ], [ [ -73.977692 73.977692, , 40.763598 40.763598], ], [ [ -73.979508 73.979508, , 40.761269 40.761269 ], ], [ [ -73.982364 73.982364, , 40.762358 40.762358 ], ], [ [ -73.983692 73.983692, , 40.760497 40.760497 ], ], [ [ -73.972821 73.972821, , 40.755861 40.755861 ], ], [ [ -73.969581 73.969581, , 40.760331 40.760331 ] ] ] } Defines a business service area 36
Big Polygon
I am an airplane at [0, 0] What airports are within my flight range? 4 3 1 2 Start with a plane with a medium sized flight range polygon
I am an airplane at [0, 0] What airports are within my flight range? 4 3 1 2 If it’s a longer range plane, that polygon gets bigger
I am an airplane at [0, 0] What airports are within my flight range? 4 3 1 2 Eventually polygon get so big it covers more than 50% of the planet
urn:x-mongodb:crs:strictwinding:EPSG:4326 • urn – Uniform resource name • x-mongodb – MongoDB extension • strictwinding – Enforces explicit “counter-clockwise” winding – a.k.a. • anGclockwise, • right hand rule • the correct way • ESPG:4326 – Another name for WGS84 (the standard web geo coordinate system) 41
How do I do that? // build some geo JSON var var crs crs = = "urn:x-mongodb:crs:strictwinding:EPSG:4326" "urn:x-mongodb:crs:strictwinding:EPSG:4326" var var bigCRS bigCRS = = { type { type : : "name" "name", properties , properties : : { name { name : : crs crs } }; } }; var bigPoly var bigPoly = = { type { type : : "Polygon" "Polygon", , coordinates : : [ [[ [[-10.0 10.0, , -10.0 10.0], ], [10.0 10.0, , -10.0 10.0], ], [10.0 10.0, , 10.0 10.0], ], [-10.0 10.0, , 10.0 10.0], ], [-10.0 10.0, , -10.0 10.0]]], ]]], crs : : bigCRS bigCRS }; }; var var cursor cursor = = db db.<collection collection>.find({ .find({ loc : : { $ { $geoWithin geoWithin : : { $ { $geometry geometry : : bigPoly bigPoly } } } } }); }); var var cursor cursor = = db db.<collection collection>.find find({ ({ loc : : { $ { $geoIntersects geoIntersects : : { $ { $geometry geometry : : bigPoly bigPoly } } } } }); }); 42
Complex Polygons 43
Complex Polygons { { "type" "type": : "Polygon" "Polygon", "coordinates" : : [ [ [ [ -73.969581 73.969581, , 40.760331 40.760331 ], ], [ [ -73.974487 73.974487, , 40.762245 40.762245 ], ], [ [ -73.977692 73.977692, , 40.763598 40.763598], ], … ], ], [ [ [ -73.975181 73.975181, , 40.758494 40.758494 ], ], [ [ -73.973336 73.973336, , 40.760965 40.760965 ], ], [ [ -73.974924 73.974924, , 40.761663 40.761663 ], ], .. .. ], ], [ [ [ -73.979437 73.979437, , 40.755390 40.755390 ], ], [ [ -73.976953 73.976953, , 40.754362 40.754362 ], ], [ [ -73.978364 73.978364, , 40.752448 40.752448 ], ], …] ] ] ] } 44
Recommend
More recommend