如何查询从一个区域到另一个区域的所有空间轨迹
How to query all spatial trajectories that go from one region to another
考虑一个 mongo 数据库,其中每个文档对应一个空间轨迹。也就是说,有一个字段包含每个文档的数组。每个数组都是 latitude/longitude 对的序列,表示地理轨迹。给定两个由 geojson 多边形定义的地理区域 R1、R2,找到所有与第一个 R1 和第二个 R2 相交的轨迹。鉴于数据库的大小,计算时间非常重要。
我的第一次尝试成功了,但没有考虑方向。而且,它非常慢。我使用聚合框架(区域 gjs[i])。我当前的管道包含以下内容。
{"$match":{"location.lonlat":{'$geoIntersects':{'$geometry':gjs[0]}}}}, {"$match":{"location.lonlat":{'$geoIntersects':{'$geometry':gjs[1]}}}}
来自 the MongoDB manual :
$geoIntersects 使用球面几何。 $geoIntersects 不需要地理空间索引。但是,地理空间索引将提高查询性能。只有 2dsphere 地理空间索引支持 $geoIntersects。
所以您遇到了一个问题:您的查询有效是因为 $geoIntersects
不需要 需要索引,但它很慢,因为没有索引。要加快速度,您必须创建一个 2dsphere
索引,因为这是 $geoIntersects
使用的唯一索引(即不是 2d
索引)——不幸的是 不会在遗留坐标点数组(您的“轨迹”)上工作。
我的建议是使用完整的 GeoJSON:
- 将您的
location.lonlat
点数组转换为 GeoJSON LineString
对象,例如
{location: {
"trajectory" : {
"type" : "LineString",
"coordinates" : [ [10,60] , [10,61] , [10,62] ]
}
},
您可以通过 非破坏性 更新来创建一个新字段 trajectory
作为 lonlat
在 location
目的。请注意使用允许管道的 update()
数组形式,因此可以将 $location.lonlat
数组复制到新字段中:
db.foo.update({}, [ {$set: {"location.trajectory": {type: "LineString", coordinates: "$location.lonlat"}}} ], {multi:true});
- 在
location.trajectory
上创建一个 2dsphere
索引:
db.foo.createIndex({"location.trajectory":"2dsphere"});
您的查询现在将是高效的。
考虑一个 mongo 数据库,其中每个文档对应一个空间轨迹。也就是说,有一个字段包含每个文档的数组。每个数组都是 latitude/longitude 对的序列,表示地理轨迹。给定两个由 geojson 多边形定义的地理区域 R1、R2,找到所有与第一个 R1 和第二个 R2 相交的轨迹。鉴于数据库的大小,计算时间非常重要。
我的第一次尝试成功了,但没有考虑方向。而且,它非常慢。我使用聚合框架(区域 gjs[i])。我当前的管道包含以下内容。
{"$match":{"location.lonlat":{'$geoIntersects':{'$geometry':gjs[0]}}}}, {"$match":{"location.lonlat":{'$geoIntersects':{'$geometry':gjs[1]}}}}
来自 the MongoDB manual :
$geoIntersects 使用球面几何。 $geoIntersects 不需要地理空间索引。但是,地理空间索引将提高查询性能。只有 2dsphere 地理空间索引支持 $geoIntersects。
所以您遇到了一个问题:您的查询有效是因为 $geoIntersects
不需要 需要索引,但它很慢,因为没有索引。要加快速度,您必须创建一个 2dsphere
索引,因为这是 $geoIntersects
使用的唯一索引(即不是 2d
索引)——不幸的是 不会在遗留坐标点数组(您的“轨迹”)上工作。
我的建议是使用完整的 GeoJSON:
- 将您的
location.lonlat
点数组转换为 GeoJSONLineString
对象,例如
{location: {
"trajectory" : {
"type" : "LineString",
"coordinates" : [ [10,60] , [10,61] , [10,62] ]
}
},
您可以通过 非破坏性 更新来创建一个新字段 trajectory
作为 lonlat
在 location
目的。请注意使用允许管道的 update()
数组形式,因此可以将 $location.lonlat
数组复制到新字段中:
db.foo.update({}, [ {$set: {"location.trajectory": {type: "LineString", coordinates: "$location.lonlat"}}} ], {multi:true});
- 在
location.trajectory
上创建一个2dsphere
索引:
db.foo.createIndex({"location.trajectory":"2dsphere"});
您的查询现在将是高效的。