Pesquisar geoespacialmente
Nesta página
Visão geral
Neste guia, você pode aprender como pesquisar dados geoespaciais com o MongoDB Java Driver e os diferentes formatos de dados geoespaciais suportados pelo MongoDB.
Dados geoespaciais são dados que representam uma localização geográfica na superfície da Terra. Exemplos de dados geoespaciais incluem:
Localizações de cinemas
Fronteiras de países
Rotas de passeios de bicicleta
Áreas de exercícios para cães na cidade de Nova York
Coordenadas na Terra
Para armazenar e fazer query dos seus dados geoespaciais no MongoDB, utilize GeoJSON. GeoJSON é um formato de dados criado pela Internet Engineering Task Force (IETF).
Aqui está a localização da sede do MongoDB no GeoJSON:
"MongoDB Headquarters" : { "type": "point", "coordinates": [-73.986805, 40.7620853] }
Para obter informações sólidas sobre o GeoJSON, consulte a especificação oficial do IETF.
Posições GeoJSON
Uma posição representa um único local na Terra e existe em código como uma array contendo dois ou três valores numéricos:
Longitude na primeira posição (obrigatório)
Latitude na segunda posição (obrigatório)
Elevação na terceira posição (opcional)
Importante
Longitude e depois latitude
A GeoJSON ordena coordenadas como longitude primeiro e latitude segundo. Isto pode ser surpreendente como convenções do sistema de coordenadas geográficas geralmente listam latitude primeiro e longitude segundo. Certifique-se de verificar qual formato qualquer outra ferramenta com a qual você está trabalhando usa. Ferramentas populares como OpenStreetMap e Google Maps listam coordenadas como latitude primeiro e longitude segundo.
Tipos de GeoJSON
O tipo de objeto GeoJSON determina sua forma geométrica. Formas geométricas são compostas por posições.
Aqui estão alguns tipos de GeoJSON comuns e como você pode especificá-los com posições:
Point
: uma única posição. Isso pode representar a localização de uma construção.LineString
: uma matriz de duas ou mais posições, formando assim uma série de segmentos de linha. Isso pode representar a rota da Grande Muralha da China.Polygon
: uma array de posições em que a primeira e a última posição são iguais, contendo algum espaço. Isso pode representar o território dentro da Cidade do Vaticano.
Para saber mais sobre as formas que você pode usar no MongoDB, consulte a entrada do manual GeoJSON.
Index
Para query dados armazenados no formato GeoJSON, adicione o campo que contém dados GeoJSON a um índice do 2dsphere
. O seguinte trecho cria um índice 2dsphere
no campo location.geo
utilizando o construtor Indexes
:
// <MongoCollection setup code here> collection.createIndex(Indexes.geo2dsphere("location.geo"));
Para obter mais informações sobre o construtor Indexes
, consulte nosso guia sobre o construtor de índices.
Coordenadas em um plano 2D
Você pode armazenar dados geoespaciais utilizando coordenadas do x
e y
em um plano Euclidiano bidimensional. Nos referimos a coordenadas em um plano bidimensional como "legacy coordinate pairs".
Os legacy coordinate pairs têm a seguinte estrutura:
"<field name>" : [ x, y ]
Seu campo deve conter uma array de dois valores em que o primeiro representa o valor do eixo x
e o segundo representa o valor do eixo y
.
Index
Para query dados armazenados como legacy coordinate pairs, você deve adicionar o campo que contém legacy coordinate pairs a um índice 2d
. O seguinte trecho cria um índice 2d
no campo coordinates
utilizando o construtor Indexes
:
// <MongoCollection setup code here> collection.createIndex(Indexes.geo2d("coordinates"));
Para obter mais informações sobre o construtor Indexes
, consulte nosso guia sobre o construtor de índices.
Para mais informações sobre legacy coordinate pairs, consulte a página manual do servidor MongoDB sobre legacy coordinate pairs.
Dica
Operadores suportados
Os índices esféricos (2dsphere
) e planos (2d
) suportam alguns, mas não todos, dos mesmos operadores de query. Para uma lista completa de operadores e sua compatibilidade de índice, consulte a entrada manual para queries geoespaciais.
Consultas geoespaciais
As queries geoespaciais consistem em um operador de query e formas GeoJSON como parâmetros de query.
Operadores de Consulta
Para fazer query de seus dados geoespaciais, utilize um dos seguintes operadores de query:
$near
$geoWithin
$nearSphere
$geoIntersects
requer um índice de 2dsphere
Você pode especificar esses operadores de query no driver Java do MongoDB com os métodos utilitários near()
, geoWithin()
, nearSphere()
e geoIntersects()
da classe de construtor Filters
.
Para mais informações sobre operadores de query geoespacial, consulte a entrada manual para queries geoespaciais.
Para obter mais informações sobre Filters
, consulte nosso guia sobre o construtor de filtros.
parâmetros de query
Para especificar uma forma para utilizar em uma query geoespacial, utilize as classes Position
, Point
, LineString
e Polygon
do driver Java do MongoDB.
Para obter uma lista completa das formas GeoJSON disponíveis no driver Java do MongoDB, consulte o pacote GeoJSON Documentação da API.
Exemplos
Os exemplos seguintes utilizam o conjunto de dados de amostra do MongoDB Atlas. Você pode aprender como definir seu próprio Atlas cluster de camada grátis e como carregar o conjunto de dados de exemplo em nosso guia de início rápido.
Os exemplos utilizam a coleção do theaters
no banco de dados do sample_mflix
a partir do conjunto de dados de amostra. A coleção theaters
contém um índice 2dsphere
no campo location.geo
.
Os exemplos exigem as seguintes importações:
import java.util.Arrays; import org.bson.conversions.Bson; import com.mongodb.client.model.geojson.Point; import com.mongodb.client.model.geojson.Polygon; import com.mongodb.client.model.geojson.Position; import static com.mongodb.client.model.Filters.near; import static com.mongodb.client.model.Filters.geoWithin; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.excludeId;
Você pode encontrar o código fonte para os exemplos no Github aqui.
Query por proximidade
Para pesquisar e retornar documento do mais próximo para o mais distante de um ponto, use o método de utilidade estática near()
da classe de construtor Filters
. O método near()
constrói uma query com o operador de query $near
.
O exemplo a seguir consulta os cinemas entre 10,000
e 5,000
metros do Grande Gramado do Central Parque.
// Add your MongoClient setup code here MongoDatabase database = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> collection = database.getCollection("theaters"); Point centralPark = new Point(new Position(-73.9667, 40.78)); // Creates a query that matches all locations between 5,000 and 10,000 meters from the specified Point Bson query = near("location.geo", centralPark, 10000.0, 5000.0); // Creates a projection to include only the "location.address.city" field in the results Bson projection = fields(include("location.address.city"), excludeId()); // Prints the projected field of the results from the geospatial query as JSON collection.find(query) .projection(projection) .forEach(doc -> System.out.println(doc.toJson()));
A saída do trecho de código deve ser semelhante a esta:
{"location": {"address": {"city": "Bronx"}}} {"location": {"address": {"city": "New York"}}} {"location": {"address": {"city": "New York"}}} {"location": {"address": {"city": "Long Island City"}}} {"location": {"address": {"city": "New York"}}} {"location": {"address": {"city": "Secaucus"}}} {"location": {"address": {"city": "Jersey City"}}} {"location": {"address": {"city": "Elmhurst"}}} {"location": {"address": {"city": "Flushing"}}} {"location": {"address": {"city": "Flushing"}}} {"location": {"address": {"city": "Flushing"}}} {"location": {"address": {"city": "Elmhurst"}}}
Dica
Curiosidade
O MongoDB utiliza o mesmo sistema de referência que os Satélites gps para calcular geometrias sobre a Terra.
Para obter mais informações sobre o operador $near
, consulte a documentação de referência de $near.
Para obter mais informações sobre Filters
, consulte nosso guia sobre o construtor de filtros.
Query dentro de um intervalo
Para pesquisar dados geoespaciais dentro de uma forma especificada, utilize o método de utilidade estática geoWithin()
da classe de construtor Filters
. O método geoWithin()
constrói uma query com o operador de query $geoWithin
.
O exemplo a seguir pesquisar cinemas em uma seção de Long Console.
// Add your MongoCollection setup code here // Creates a set of points that defines the bounds of a geospatial shape Polygon longIslandTriangle = new Polygon(Arrays.asList(new Position(-72, 40), new Position(-74, 41), new Position(-72, 39), new Position(-72, 40))); // Creates a projection to include only the "location.address.city" field in the results Bson projection = fields(include("location.address.city"), excludeId()); // Creates a query that matches documents containing "location.geo" values within the specified bounds Bson geoWithinComparison = geoWithin("location.geo", longIslandTriangle); // Prints the projected field of the results from the geolocation query as JSON collection.find(geoWithinComparison) .projection(projection) .forEach(doc -> System.out.println(doc.toJson()));
A saída do trecho de código deve ser semelhante a esta:
{"location": {"address": {"city": "Baldwin"}}} {"location": {"address": {"city": "Levittown"}}} {"location": {"address": {"city": "Westbury"}}} {"location": {"address": {"city": "Mount Vernon"}}} {"location": {"address": {"city": "Massapequa"}}}
A figura a seguir mostra o polígono definido pela variável longIslandTriangle
e os pontos que representam as localizações dos cinemas retornados por nossa query.
Para mais informações sobre o operador $geoWithin
, consulte a documentação de referência para $geoWithin
Para obter mais informações sobre os operadores que você pode usar em sua query, consulte a página manual doMongoDB Server em operadores de query geoespacial