地理空间搜索
概述
在本指南中,您可以学习如何使用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页面。
旧坐标对
使用旧坐标对来表示二维欧几里得平面上的地理空间数据。
以下代码指定了一个旧坐标对,表示华盛顿特区的位置。
let capital = vec! [-77.0369, 38.9072];
要了解更多关于旧坐标对的信息,请参阅服务器手册中的旧坐标对。
地理空间索引
在查询地理空间数据之前,您必须创建一个与数据格式相对应的索引。以下索引类型支持地理空间查询:
2dsphere
用于 GeoJSON 数据2d
用于旧坐标对
以下关于 2dsphere
和 2d
索引的部分包含使用 theaters
集合的代码示例,该集合来自 Atlas 样例数据中的 sample_mflix
数据库。
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
数据库中的theaters
集合的代码示例。假设theaters
集合在location.geo
字段上有一个2dsphere
索引。
查询运算符
要查询你的地理空间数据,请使用以下查询运算符
$near
$geoWithin
$nearSphere
$geoIntersects
(需要2dsphere索引)
当使用$near
运算符时,您可以指定以下距离运算符
$minDistance
$maxDistance
当使用$geoWithin
运算符时,您可以指定以下形状运算符
$box
$polygon
$center
$centerSphere
提示
有关地理空间查询运算符的更多信息,请参阅服务器手册中的地理空间查询运算符。
邻近查询示例
以下示例查询在纽约市纽约的MongoDB总部1000米范围内的location.geo
字段存储位置的文档。代码按距离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文档