GeoJSON和MongoDB:将点存储为GeoJSON.Point值得吗?

GeoJSON和MongoDB:将点存储为GeoJSON.Point值得吗?,mongodb,gis,wgs84,database,Mongodb,Gis,Wgs84,Database,随着2.3>的引入MongoDB在位置数据处理和查询方面变得更加有用。MongoDB将文档存储为BSON,因此每个文档都具有所有文档字段,这显然会导致比传统RMDB更大的数据库 我曾经将多段线和多边形存储为一系列索引点,并使用一个额外的字段表示每条线的顺序(我这样做是为了确保使用JavaScript时的一致性,因此点并不总是以正确的顺序存储)。是这样的: polyline: { [ point: [0,0], order: 0 ], [ point: [0,1

随着
2.3>的引入
MongoDB在位置数据处理和查询方面变得更加有用。MongoDB将文档存储为BSON,因此每个文档都具有所有文档字段,这显然会导致比传统RMDB更大的数据库

我曾经将多段线和多边形存储为一系列索引点,并使用一个额外的字段表示每条线的顺序(我这样做是为了确保使用JavaScript时的一致性,因此点并不总是以正确的顺序存储)。是这样的:

polyline: {
  [
    point: [0,0],
    order: 0
  ],
  [
    point: [0,1],
    order: 1
  ]
}
而现在我使用:

polyline: {
  type: 'LineString',
  coordinates: [
    [0,0],
    [1,0]
  ]
}
我已经看到文档大小的改进,因为一些多段线最多可以有500个点

但是,我想知道将所有
数据存储为
GeoJSON
会有什么好处。我对文档大小的增加感到气馁,例如:

loc: [1,0]
是不是比

loc: {
  type: 'Point',
  coordinates: [0,1]
}
这样就更容易合作了

我的问题是:

与2点数组相比,将点存储为
GeoJSON
对象是否更好?

我所考虑的是:

  • 大小限制:我可能有数百万个文档,它们的位置可能会影响收藏的大小,也可能会影响我的口袋
  • 一致性:最好处理
    lng,lat
    格式中的每一组坐标,而不是坚持点的
    lat,lng
    ,以及我的所有其他位置特征的前一组坐标
  • 便利性:如果我抓住一个点,并使用
    $geoinsin
    $geocintersects
    与它一起使用,在将它用作
    查询
    参数之前,我不需要先将其转换为GeoJSON
我不确定的是:

  • 将来是否会在MongoDB上放弃对
    loc:[x,y]
    的支持
  • 任何索引都得益于
    2dsphere
    ,而不是
    2d
  • MongoDB中任何计划的
    GeoJSON
    添加是否会导致需要上述一致性
我宁愿在我的数据仍然可以管理的时候转移到
GeoJSON
,也不愿在未来的压力下切换

请允许我提出一个经过深思熟虑的答案。我不会很快选择正确的答案,所以我可以评估任何回答


我也不确定这是否是提出问题的正确地点,因此如果DBA是一个更合适的地点,我将把问题转移到那里。我选择这样做是因为这里有很多与MongoDB相关的活动。

是的,我认为这是值得的。根据我使用地理空间信息系统的经验,最好将您的位置数据存储在一个有用且可转移的标准中。MongoDB中的GeoJSON支持基准标准

在MongoDB中,操作员可以搜索传统的2d坐标和GeoJSON坐标。在传统二维坐标集合上,$near返回最接近的第一个排序集合。返回距离搜索点元数据最近的第一个排序集合

另一个好处是能够使用其他地理空间查询(即$GeoInner和$geoIntersect),特别是在存储其他GeoJSON类型(多段线、多边形)时

最后


我希望这些信息能为您提供一些关于如何处理位置数据的思考点。

我建议使用新的GeoJSON格式。虽然我不认为有人宣布放弃对旧格式的支持,但他们将其称为遗产的事实应该表明他们的观点

使用2dsphere而不是2d有一些索引好处

  • 首先,它实际上是基于地球是一个球体来计算查询。2d索引的缺点之一是它没有考虑到这一点,这意味着如果您对查询所覆盖的实际区域而不是基本lat/lngs感兴趣,则必须自己处理转换
  • 使用复合索引的能力,如果您想执行“首先从这个区域获取100个最新结果”,那么2dsphere是您唯一的选择
  • 使用geoIntersects查询的能力
  • GeoIn geometry查询要求使用geoJSON格式
另一个需要注意的重要事项是,您需要确保所使用的索引支持您正在使用的查询。例如,如果您使用2dsphere,您不能使用$box查询,因为它不会被索引-但是mongo不会警告您-结果只会执行表扫描,速度会非常慢


如果您只在数据库中存储点几何图形,但希望对该数据支持多个不同的GeoJSON查询,请注意,可以使用传统坐标对格式存储点,并使用
2dsphere
索引

对于mongoose的GeoJSON支持(MongoDB>=2.4)给出以下示例:

2dsphere
传统坐标对索引:

new Schema({ 
    loc: { type: [Number], index: '2dsphere'}
});
var geojsonPoly = { 
    type: 'Polygon', 
    coordinates: [[[-5,-5], ['-5',5], [5,5], [5,-5],[-5,'-5']]] 
};

Model.find({ loc: { $within: { $geometry: geojsonPoly }}});
GeoJSON
使用
2dsphere
索引查询传统坐标对:

new Schema({ 
    loc: { type: [Number], index: '2dsphere'}
});
var geojsonPoly = { 
    type: 'Polygon', 
    coordinates: [[[-5,-5], ['-5',5], [5,5], [5,-5],[-5,'-5']]] 
};

Model.find({ loc: { $within: { $geometry: geojsonPoly }}});

根据我目前的经验,我可以将Mongo的所有地理查询与遗留对一起使用,包括
$geoNear
。因此,我没有注意到查询类型的任何差异。我有另一个应用程序,它对所有位置数据使用
GeoJSON
,所以我在这里谈论的是两者之间的比较。我以lat,lng格式存储点数据,并编写了一个实用程序,可将
GeoJSON
转换为数组并返回。因此,从方便的角度来看,这没有什么区别。我更担心Mongo2.6将来的兼容性,所以我接受你的答案。你的第二点让我信服