Localizando uma Agulha: usando MongoDB para dados Geolocalizados

Preview:

Citation preview

Globalcode – Open4education

Globalcode – Open4education

Trilha – NoSQLCaliel Costa

Nerd, ouvinte de blues, pesquisador, esportista e fotógrafo amador, desenvolvedor e projetista de soluções em TI. Software Designer no Superplayer.

Globalcode – Open4education

Agenda

• Telecurso de Geografia• Necessidade• GeoJSON• Consultas• Dados

Globalcode – Open4education

Planeta Terra

Caliel Costa
http://www.studyzone.org/testprep/ss5/b/comcontoclinesl.cfm

Globalcode – Open4education

Planeta Terra

Degrees, Minutes, Seconds to/from Decimal Degrees

Cidade Latitude Longitude

Porto Alegre -30.03128-30° 1' 52.6074" Sul

-51.212548751° 12' 45.1764" Oeste

São Paulo -23.598877-23° 35' 55.9572" Sul

-46.6749596-46° 40' 29.8554" Oeste

Londres 51.499443851° 29' 57.9978" Norte

00° 0' 0"

Hong Kong 22.357678222° 21' 27.6402" Norte

114.2196956114° 13' 10.905" Leste

Globalcode – Open4education

Planeta Terra em Polígonos(21 pontos)

Globalcode – Open4education

Planeta Terra em Polígonos(84 Pontos)

Globalcode – Open4education

Planeta Terra em Polígonos(338 Pontos)

Globalcode – Open4education

Superplayer é um serviço de recomendação musical focado em melhorar todos os momentos da vida das pessoas através da trilha sonora perfeita.

Startup brasileiraCriado em 2012

Globalcode – Open4education

Web, Android, iOS, Windows Phone, ...

+ 8.500.000USUÁRIOS ÚNICOS

ACUMULADOS

+ 1.400.000USUÁRIOS ÚNICOS POR MÊS

+ 4.500.000VISITAS POR MÊS

Globalcode – Open4education

MongoDB

Na versão 2.4 (em 2013) foi introduzido o suporte a geometrias GeoJSON, podendo ser usadas em data e consultas.

Globalcode – Open4education

GeoJSON

type coordinates

Point deve ser uma posição simples

MultiPoint deve ser um array de posição

LineString deve ser um array de 2 ou mais posições

MultiLineString deve ser um array de array de LineString

Polygon deve ser um LinearRing, ou seja um LineString com 4 ou mais pontos, onde o primeiro e o último são posições equivalentes

MultiPolygon deve ser um array de array de Polygon

Globalcode – Open4education

GeoJSON - Point

{ "type": "Point", "coordinates": [100.0, 0.0],}

Globalcode – Open4education

GeoJSON - LineString

{ "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ],}

Globalcode – Open4education

GeoJSON - Polygon

{ "type": "Polygon", "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ],}

Globalcode – Open4education

GeoJSON - MultiPoint

{ "type": "MultiPoint", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ],}

Globalcode – Open4education

GeoJSON - MutiLineString

{ "type": "MultiLineString", "coordinates": [ [ [100.0, 0.0], [101.0, 1.0] ], [ [102.0, 2.0], [103.0, 3.0] ] ]}

Globalcode – Open4education

GeoJSON - MultiPolygon

{ "type": "MultiPolygon", "coordinates": [ [ [ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ] ], [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ], [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ] ] ]}

Globalcode – Open4education

Brazil, seus 27 estados e respectivas capitais

Globalcode – Open4education

GeoJSON - Brasil

{ "_id" : ObjectId("54f4bd437da3100f4454e812"), "level" : "Country", "name" : "Brasil (BR)", "loc" : { "type" : "Polygon", "coordinates" : [ [ [ -44.69501, -1.817778 ], … 336 ... [-44.69501, -1.817778 ] ] ] }}

Globalcode – Open4education

GeoJSON - Estado São Paulo

{ "_id" : ObjectId("54f4bd5b7da3100f4454e82c"), "parentid" : "54f4bd437da3100f4454e812", "level" : "State", "name" : "São Paulo (SP)", "loc" : { "type" : "Polygon", "coordinates" : [ [ [ -49.3352376, -24.2290424 ], ...497... [ -49.3352376, -24.2290424 ] ] ] }}

Globalcode – Open4education

GeoJSON - Cidade São Paulo

{ "_id" : ObjectId("54f4bd5d7da3100f4454e846"), "parentid" : "54f4bd5b7da3100f4454e82c", "level" : "City", "name" : "São Paulo", "loc" : { "type" : "Polygon", "coordinates" : [ [ [ -46.53766020909132, -23.36963320731797 ], ..310.. [ -46.53766020909132, -23.36963320731797 ] ] ] }}

Globalcode – Open4education

Longitude e Latitude Vs Latitude e Longitude

{ "loc" : { "type" : "Polygon", "coordinates" : [ [ [ -46.53766020909132, -23.36963320731797 ], ..310.. [ -46.53766020909132, -23.36963320731797 ] ] ] }}

Cidade Latitude Longitude

São Paulo -23.598877-23° 35' 55.9572" Sul

-46.6749596-46° 40' 29.8554" Oeste

Globalcode – Open4education

Longitude e Latitude Vs Latitude e Longitude

“All documents must store location data in the same order. If you use latitude and longitude as your coordinate system, always store longitude first. MongoDB’s 2d spherical index operators only recognize [longitude, latitude] ordering.”

Globalcode – Open4education

Indexando GeoJSON

Tipo Uso

2dsphere Suporta consultas que calculem geometrias em uma esfera tipo a Terra.

2d Gera um geohash de acordo com o valor das coordenadas

haystack Este índice é um tipo especial de índice otimizado para retornar resultados sobre areas pequenas

Globalcode – Open4education

Indexando GeoJSON

db.locations.createIndex({ "loc" : "2dsphere"}, { "name" : "loc_"})

• Índice esparso• Não pode ser usado como chave de sharding

Globalcode – Open4education

Consultas GeoJSON

Function Objetivo

$geoWithin Seleciona geometrias dentro dos limites de outra

$geoIntersects Seleciona geometrias em interção com outra

$near Retorna objetos na proximidade de um ponto

$nearSphere Retorna objetos na proximidade de um ponto na esfera

Globalcode – Open4education

Onde estou?

query: { "loc": { $geoIntersects: { $geometry: { type: "Point" , coordinates: [-51.2125487, -30.03128] } } }}

Globalcode – Open4education

Onde estou?

query: { "loc": { $geoIntersects: { $geometry: { type: "Point" , coordinates: [-51.2125487, -30.03128] } } }}

Result:Brasil (BR)Rio Grande do Sul (RS)Porto Alegre

Globalcode – Open4education

Onde estou??

query: { "loc": { $geoIntersects: { $geometry: { type: "Point" , coordinates: [-46.6749596, -23.598877] } } }}

Globalcode – Open4education

Onde estou??

query: { "loc": { $geoIntersects: { $geometry: { type: "Point" , coordinates: [-46.6749596, -23.598877] } } }}

Result:Brasil (BR)São Paulo (SP)São Paulo

Globalcode – Open4education

Cidades perto de Gramado/RS

{ "level": "City", "loc": { $near: { $geometry: { type: "Point", coordinates: [-50.8586806,-29.3851463] } $minDistance: 1, $maxDistance: 300000, }, }}

Globalcode – Open4education

Cidades perto de Gramado/RS

{ "level": "City", "loc": { $near: { $geometry: { type: "Point", coordinates: [-50.8586806,-29.3851463] } $minDistance: 1, $maxDistance: 300000, }, }}

Result:Porto AlegreFlorianópolis

Globalcode – Open4education

Cidades perto de Campinas/SP

query: { "level": "City", "loc": { $near: { $geometry: { type: "Point", coordinates: [-47.0562422, -22.9084404] } $minDistance: 60000, $maxDistance: 80000, } , }}

Globalcode – Open4education

Cidades perto de Campinas/SP

query: { "level": "City", "loc": { $near: { $geometry: { type: "Point", coordinates: [-47.0562422, -22.9084404] } $minDistance: 60000, $maxDistance: 80000, } , }}

Result:Osasco, Carapicuíba, Cotia, Vargem Grande Paulista

Globalcode – Open4education

$NearSphere

Funciona igual ao Near só que ao invés de se usar distâncias em metros usa-se em radianos.

Globalcode – Open4education

Playlists

Globalcode – Open4education

Segmentação de Playlists

Globalcode – Open4education

Segmentação de Playlists

Globalcode – Open4education

Segmentação de Playlists

Globalcode – Open4education

Segmentação de Playlists

PlaylistLoc

Type Loc Name

Correndo no Ibira Polygon [ [ [long, lat] … ] ] São Paulo

Rio 40 Graus Polygon [ [ [long, lat] … ] ] Rio de Janeiro

Men’s Health Polygon [ [ [long, lat] … ] ] Brasil (BR)

Globalcode – Open4education

Buscando playlists

query: { $or: [ { "location": { $not: { $exists: true } } }, { "location": { $geoIntersects: { $geometry: { type: "Point" , coordinates: [-46.6749596, -23.598877] } } } } ],}

Result:Acorda, Peão!, Acorda, Vagabundo!, Bebendo no Boteco, Correndo no Ibira, Dia de Chuva, Men’s

Health, Trabalhando numa Boa, Whiskynho com a Rapaziada, ...

Globalcode – Open4education

Buscando playlists

query: { $or: [ { "location": { $not: { $exists: true } } }, { "location": { $geoIntersects: { $geometry: { type: "Point" , coordinates: [-47.0562422, -22.9084404] } } } } ],}

Result:Acorda, Peão!, Acorda, Vagabundo!, Bebendo no Boteco, Dia de Chuva, Men’s Health, Trabalhando

numa Boa, Whiskynho com a Rapaziada, ...

Globalcode – Open4education

Conteúdo Localizado

• Playlists• Spots• Patrocínios de Playlists

• Log de Playlists ouvidas• Log de Músicas (Tracks) ouvidas

Globalcode – Open4education

Optimização

Play

MongoDB

API Web

Play @Rock

Playlist com tracks

Rock por Caliel

Globalcode – Open4education

Optimização

APIiOS

Play @RockMongo

DB

db.locations.find({

"loc": {

$geoIntersects: { $geometry: {

type: "Point" , coordinates: [-46.6749596, -23.598877] }

}

}

}

{ _id: “ABC”, level: “Country”, name: “Brasil (BR)” },

{ _id: “DEF”, level: “State”, name: “São Paulo (SP)” },

{ _id: “GHI”, level: “City”, name: “São Paulo” },

Globalcode – Open4education

Optimização

APIiOS

Play @RockMongo

DB{ _id: “ABC”, name: “Acorda, Peão!” },

{ _id: “ABC”, name: “Acorda, Vagabundo!” },

{ _id: “ABC”, name: “Bebendo no Boteco” },

{ _id: “ABC”, name: “Correndo no Ibira” },

{ _id: “ABC”, name: “Dia de Chuva” },

{ _id: “ABC”, name: “Men’s Health” },

{ _id: “ABC”, name: “Trabalhando numa Boa” },

{ _id: “ABC”, name: “Whiskynho com a Rapaziada” },

db.playlists.find({

$or: [

{ "location": { $not: { $exists: true } } },

{ "location.name": "Brasil (BR)" },

{ "location.name": "São Paulo (SP)" },

{ "location.name": "São Paulo" },

],

}

Globalcode – Open4education

Optimização

APIiOSPlay @Rock

MongoDB

db.plays.insert({

playlist: { name: "Rock" },

geolocation: {

coordinates: [-46.6749596, -23.598877],

locations: [

{ sourceid: “ABC”, level: “Country”, name: “Brasil (BR)” },

{ sourceid: “DEF”, level: “State”, name: “São Paulo (SP)” },

{ sourceid: “GHI”, level: “City”, name: “São Paulo” },

],

}

});

Globalcode – Open4education

Closure

O MongoDB fornece toda a infraestrutura necessária para se trabalhar com dados geolocalizados de maneira simples

Não é a toa que é usado/foi feito junto com o Foursquare

A nossa estrutura está pronta para crescer. Para colocar novas cidades, basta mapea-las e importar o arquivo kml. A demanda de playlists e spots vem crescendo nos últimos meses sem que tivessemos que alterar a infraestrutura para isso.

Globalcode – Open4education

Perguntas?

Globalcode – Open4education

jointheband@superplayer.fm

Globalcode – Open4education

Documentação MongoDB

http://docs.mongodb.org/manual/applications/geospatial-indexes/

http://docs.mongodb.org/manual/reference/operator/query-geospatial/

Recommended