按地理空间搜索
Overview
在本指南中,您可以了解如何使用 Rust 驱动程序搜索地理空间数据。 地理空间数据表示地球表面或欧几里得平面上的地理位置。
地理空间数据的示例包括:
电影院位置
国家/地区边界
自行车骑行路线
纽约市的狗狗运动区
图表上的点
本指南包括以下部分:
存储地理空间数据
MongoDB 中的所有地理空间数据都使用以下格式之一存储:
GeoJSON,一种表示类似地球球体上的地理空间数据的格式
旧版坐标对,一种表示欧几里得平面上的地理空间数据的格式
GeoJSON
使用 GeoJSON 来存储表示类地球体上地理空间信息的数据。GeoJSON 由一个或多个位置和一个类型组成。
位置
位置代表地球上的单个位置,并以包含以下值的数组形式存在于代码中:
第一个位置的经度
第二个位置的纬度
以下代码代表位于纽约市的 MongoDB 总部的位置:
let coords = vec! [-73.986805, 40.7620853];
重要
经度然后纬度
GeoJSON 将坐标排序为经度在前,纬度在后。 这与地理坐标系惯例相冲突,后者通常先列出纬度,然后列出经度。 确保重新格式化坐标以符合 GeoJSON 标准。
类型
GeoJSON 对象的类型决定了它所表示的几何形状。几何形状由多个位置组成。
以下列表描述了常见的 GeoJSON 类型以及如何使用位置指定这些类型:
Point
:单个位置。 例如,以下Point
表示 MongoDB 总部的位置:let point = doc! {"name": "MongoDB HQ", "location": doc! { "type": "Point", "coordinates": vec! [-73.986805, 40.7620853], } }; LineString
:由两个或多个位置组成的大量,构成一系列线段。LineString
可以表示路径、路线、边界或任何其他线性地理空间数据。示例,以下LineString
表示中国长城的一段:let line = doc! {"name": "Great Wall of China", "location": doc! { "type": "LineString", "coordinates": vec! [ vec! [116.572, 40.430], vec! [116.570, 40.434], vec! [116.567, 40.436], vec! [116.566, 40.441] ], } }; Polygon
:位置数组,其中第一个和最后一个位置相同,并包含一些空格。 例如,以下Polygon
表示 梵蒂冈城内的土地:let polygon = doc! {"name": "Vatican City", "location": doc! { "type": "Polygon", "coordinates": vec![ vec! [ vec! [12.458, 41.906], vec! [12.458, 41.901], vec! [12.450, 41.901], vec! [12.450, 41.906], vec! [12.458, 41.906], ] ], } };
要学习;了解有关可在MongoDB中使用的GeoJSON类型的更多信息,请参阅服务器手册中的GeoJSON页面。
传统坐标对
使用legacy coordinate pairs在二维欧几里得平面上表示地理空间数据。
以下代码指定表示华盛顿特区位置的旧版坐标对:
let capital = vec! [-77.0369, 38.9072];
要了解有关legacy coordinate pairs 的更多信息,请参阅legacy coordinate pairs MongoDB Server手册中的 。
地理空间索引
在查询地理空间数据之前,必须创建与数据格式相对应的索引。 以下索引类型支持地理空间查询:
2dsphere
用于 GeoJSON 数据2d
用于传统坐标对
以下关于 2dsphere
和 2d
索引的部分包括代码示例,这些示例使用来自 Atlas 样本数据的 sample_mflix
数据库中的 theaters
集合。
2dsphere
要查询以 GeoJSON 格式存储的数据,请将包含type
和coordinates
字段的字段添加到2dsphere
索引中。 以下示例在location.geo
字段上创建2dsphere
索引:
let index = IndexModel::builder() .keys(doc! { "location.geo": "2dsphere" }) .build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: location.geo_"2dsphere"
2d
要查询存储为传统坐标对的数据,请将包含传统坐标对的字段添加到2d
索引中。 以下示例在location.geo.coordinates
字段上创建2d
索引:
let index = IndexModel::builder() .keys(doc! { "location.geo.coordinates": "2d" }) .build(); let idx = my_coll.create_index(index).await?; println!("Created index:\n{}", idx.index_name);
Created index: location.geo.coordinates_"2d"
地理空间查询
在包含地理空间数据的字段上创建2dsphere
或2d
索引后,您可以执行访问这些字段的地理空间查询。
要查询地理空间数据,请使用字段名称和查询操作符创建查询筛选器。您可以为某些地理空间查询操作符指定选项,以限制返回的文档。
以下有关地理空间查询的部分包括使用来自 Atlas 样本数据的数据库sample_mflix
中的collectiontheaters
的代码示例。theaters
假设collection在 字段上有一个2dsphere
location.geo
索引。
查询运算符
要查询地理空间数据,请使用以下查询运算符之一:
$near
$geoWithin
$nearSphere
$geoIntersects
(需要 2dsphere 索引)
使用 $near
操作符时,可以指定以下距离操作符:
$minDistance
$maxDistance
使用 $geoWithin
操作符时,可以指定以下形状操作符:
$box
$polygon
$center
$centerSphere
按邻近度查询示例
以下示例查询其中location.geo
字段存储距离纽约市 MongoDB 总部 1000 米范围内的位置的文档。 该代码按与 MongoDB 总部的距离升序返回文档。
let mongodb = vec! [-73.986805, 40.7620853]; let query = doc! {"location.geo": doc! { "$near": { "$geometry": { "type": "Point", "coordinates": mongodb, }, "$maxDistance": 1000, } } }; let mut cursor = my_coll.find(query).await?; while let Some(doc) = cursor.try_next().await? { println!("{}", doc); }
{ "_id":{...},"theaterId":1908,"location":{"address":{...},"geo":{"type":"Point","coordinates":[-73.983487,40.76078] } } } { "_id":{...},"theaterId":1448,"location":{"address":{...},"geo":{"type":"Point","coordinates":[-73.982094,40.769882] } } }
范围内查询示例
以下示例查询location.geo
字段存储芝加哥地区内位置的文档。 该示例创建了一个名为chicago
的向量,其中存储了表示地理搜索区域边界的四个坐标。
let chicago = doc! { "type": "Polygon", "coordinates": vec![ vec![ vec![-87.851, 41.976], vec![-87.851, 41.653], vec![-87.651, 41.653], vec![-87.651, 41.976], vec![-87.851, 41.976], ] ] }; let query = doc! {"location.geo": doc! { "$geoWithin": { "$geometry": chicago }} }; let mut cursor = my_coll.find(query).await?; while let Some(doc) = cursor.try_next().await? { println!("{}", doc); }
{ "_id":{...},"theaterId":322,"location":{"address":{...},"geo":{ "type":"Point","coordinates":[-87.849403, 41.90707] } } } { "_id":{...},"theaterId":2960,"location":{"address":{...},"geo":{ "type":"Point","coordinates":[-87.811262, 41.847938] } } } { "_id":{...},"theaterId":323,"location":{"address":{...},"geo":{ "type":"Point","coordinates":[-87.653557, 41.912025] } } } { "_id":{...},"theaterId":320,"location":{"address":{...},"geo":{ "type":"Point","coordinates":[-87.805817, 41.847572] } } } { "_id":{...},"theaterId":814,"location":{"address":{...},"geo":{ "type":"Point","coordinates":[-87.670631, 41.919514] } } }
更多信息
要了解有关查找操作的更多信息,请参阅检索数据指南。
要了解有关使用地理空间数据的更多信息,请参阅以下服务器手册页:
API 文档
要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档: