MongoDB - Geospatial
Geospatial predstavlja data-u koja daje informacije o geografskoj lokaciji. U MongoDB, ona se može čuvati, indeksirati i mogu se vršiti pretrage na osnovu geografskih parametara.
MongoDB podržava tri tipa indeksa za Geospatial upite:
- 2D Index - koristi jednostavne koordinate (longitude, latitude),i koristi se za čuvanje tačaka dvodimenzionalnih polja.
- 2d Sphere Index - omogućava pretragu svih geometrijskih tačaka na "earth-like" sferi, i ona je danas najčeśće korišćena. Data se može sačuvatio kao GeoJSON pri čemu se koristi i par koordinata (longitude, latitude).
- Geo Haystack - koristi se za upite na veoma malim oblastima. Danas se retko koristi.
GeoJSON je format za kodiranje raznih geografskih data struktura. Podržava sledeće tipove:
- Point
- LineString
- Polygon
- MultiPoint
- MultiLineString
- MultiPolygon
- Geometry
Bitno da se koordinate čuvaju u sledećem redosledu longitude, latitude. Primer point GeoJSON-a koji predstavlja Beograd je sledeći
{
"type": "Point",
"coordinates": [
20.457273,
44.787197
]
}
Za testiranje svojih koordinata možete da koristite http://geojsonlint.com/.
Sledeći primer je geometrijska kolekcoija MultiLineString i Polygon-a preko Central Park-a u New York-u.
{
"type" : "GeometryCollection",
"geometries" : [
{
"type" : "Polygon",
"coordinates" : [
[
[ -73.9580, 40.8003 ],
[ -73.9814, 40.7681 ],
[ -73.9737, 40.7648 ],
[ -73.9498, 40.7968 ],
[ -73.9580, 40.8003 ]
]
]
},
{
"type" : "MultiLineString",
"coordinates" : [
[ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ],
[ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ],
[ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ],
[ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ]
]
}
]
}
Za sledeće zadatke potrebno je da se napravi nova baza sa nazivom "automobili" i importovati "automobili.json".
JSON fajl možete skinuti sa github naloga https://github.com/elab-office/mongoDB/tree/master/json
User:~/ $ mongoimport --db automobili --drop --collection prodajna_mesta --file ~/desktop/automobili.json --jsonArray
Zadatak 48 - Prikazati sva prodajna mesta automobila koja se nalaze u okolini sledećih tačaka (longitude: -114, latitude: 51) iz kolekcije prodajna_mesta _koja se nalazi unutar baze _automobili.
Pre upita neophodno je odrediti index.
Rešenje
> use automobili
switched to db automobili
> db.prodajna_mesta.createIndex({ loc: "2dsphere" })
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.prodajna_mesta.find({loc : {$near : {$geometry: {"type": "Point", "coordinates": [-114, 51]}}} }).pretty()
{
"_id" : ObjectId("5919967e6935229b9d3b5094"),
"naziv" : "Tom's Toyotas",
"tip" : "Toyota",
"loc" : {
"type" : "Point",
"coordinates" : [
-113.98040771484375,
50.93939251390387
]
}
}
{
"_id" : ObjectId("5919967e6935229b9d3b5096"),
"naziv" : "Charlie's Chevrolets",
"tip" : "Chevrolet",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.10400390625,
51.08282186160978
]
}
}
{
"_id" : ObjectId("5919967e6935229b9d3b5095"),
"naziv" : "Steve's Suzukis",
"tip" : "Suzuki",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.11773681640625,
51.09144802136697
]
}
}
...
Zadatak 49 - Prikazati prva dva prodajna mesta automobila koja se nalaze u okolini sledećih tačaka (longitude: -114, latitude: 51) iz kolekcije prodajna_mesta _koja se nalazi unutar baze _automobili.
Rešenje
> use automobili
switched to db automobili
> db.prodajna_mesta.find({loc : {$near : {$geometry: {"type": "Point", "coordinates": [-114, 51]}}} }).limit(2).pretty()
{
"_id" : ObjectId("5919967e6935229b9d3b5094"),
"naziv" : "Tom's Toyotas",
"tip" : "Toyota",
"loc" : {
"type" : "Point",
"coordinates" : [
-113.98040771484375,
50.93939251390387
]
}
}
{
"_id" : ObjectId("5919967e6935229b9d3b5096"),
"naziv" : "Charlie's Chevrolets",
"tip" : "Chevrolet",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.10400390625,
51.08282186160978
]
}
}
Zadatak 50 - Prikazati prodajna mesta automobila koja se nalaze u okolini sledećih tačaka (longitude: -114, latitude: 51) i koja prodaju Ford automobile iz kolekcije prodajna_mesta _koja se nalazi unutar baze _automobili.
Rešenje
> use automobili
switched to db automobili
> db.prodajna_mesta.createIndex({ loc: "2dsphere", "tip": 1 })
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
> db.prodajna_mesta.find({loc: {$near : {$geometry: {"type": "Point", "coordinates": [-114, 51]}}}, "tip": "Ford"}).pretty()
{
"_id" : ObjectId("5919967e6935229b9d3b5093"),
"naziv" : "Frank's Fords",
"tip" : "Ford",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.11773681640625,
51.10682735591432
]
}
}
Zadatak 51 - Prikazati prodajna mesta automobila iz kolekcije _prodajna_mesta _koja se nalazi unutar baze _automobili _koja se nalaze u sledećoj oblasti.
oblast = [[-114.19052124023438, 51.12335082548444], [-114.05593872070312, 51.11904092252057 ], [-114.02435302734375, 51.02325750523972 ], [-114.1644287109375, 51.01634653617311 ] ]
Za ovakve slučajeve koristi se $polygon
koji prima niz parova koordinata. Oni sačinjavaju jednu oblast, i sve tačke unutar te oblasti se vraćaju.
Rešenje
> use automobili
switched to db automobili
> oblast = [[-114.19052124023438, 51.12335082548444], [-114.05593872070312, 51.11904092252057 ], [-114.02435302734375, 51.02325750523972 ], [-114.1644287109375, 51.01634653617311 ] ]
[
[
-114.19052124023438,
51.12335082548444
],
[
-114.05593872070312,
51.11904092252057
],
[
-114.02435302734375,
51.02325750523972
],
[
-114.1644287109375,
51.01634653617311
]
]
> db.prodajna_mesta.find({ "loc" : {"$geoWithin" : {"$polygon" : oblast } } }).pretty()
{
"_id" : ObjectId("5919967e6935229b9d3b5093"),
"naziv" : "Frank's Fords",
"tip" : "Ford",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.11773681640625,
51.10682735591432
]
}
}
{
"_id" : ObjectId("5919967e6935229b9d3b5095"),
"naziv" : "Steve's Suzukis",
"tip" : "Suzuki",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.11773681640625,
51.09144802136697
]
}
}
{
"_id" : ObjectId("5919967e6935229b9d3b5096"),
"naziv" : "Charlie's Chevrolets",
"tip" : "Chevrolet",
"loc" : {
"type" : "Point",
"coordinates" : [
-114.10400390625,
51.08282186160978
]
}
}