首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为用于操作的MongoDB中的GeoJSON数据编制索引

为用于操作的MongoDB中的GeoJSON数据编制索引
EN

Stack Overflow用户
提问于 2013-09-20 02:24:13
回答 1查看 451关注 0票数 0

我将GeoJSON存储在用于Leaflet地图的Opa应用程序中。

到目前为止,我设法在集成的MongoDB数据库中支持PointLineString对象,其方式是将其从Opa类型转换为BSON作为正确的GeoJSON,并被小叶JS正确使用。

问题是JSON字段coordinates对于不同的几何对象具有不同的类型。对于点是位置(数字数组),对于字符串是位置数组(数字数组),对于MultiLineStrings是点数组(数字数组)

代码语言:javascript
复制
{ type: "Point", coordinates: [102.0, 0.5] }
{ type: "LineString", "coordinates": [[102.0, 0.0], [103.0, 1.0]] }
...

由于这个原因,我不能依靠type字段来区分几何对象。根据Opa documentation的说法:“如果一个sum的几个案例(即记录)共享一个标签,那么这个标签在每个案例中都必须具有相同的类型。”因此,我不能只添加字段PointLineString来区分记录类型。我必须使用嵌入了不同类型的sum类型:

代码语言:javascript
复制
type Article.geo_json_point =
  {
    string `type`,
    list(float) coordinates,
  };
type Article.geo_json_multipoint =
  {
    string `type`,
    list(list(float)) coordinates,
  };
type Article.geo_json =
  { Article.geo_json_point Point } or
  { Article.geo_json_multipoint LineString } or
  { Null };

type Article.t = {
  Article.id id,
  Article.geo_json location,
  ... // some other fields
};
database mydb {
  Article.t /article[{id}]
  /article[_]/location = {Null}
  /article[_]/location/Point/`type` = "Point"
  /article[_]/location/LineString/`type` = "LineString"
}

根据MongoDB documentation,每个集合只能创建一个地理空间索引。在这种情况下,我可以正确地存储可以索引的GeoJSON:

代码语言:javascript
复制
$ mongo mydb
> db.article.findOne({}, {_id:0, location:1})
{
    "location" : {
            "Point" : {
                    "type" : "Point",
                    "coordinates" : [
                            18.089788,
                            51.762638
                    ]
            }
    }
}

但我可以对location.Pointlocation.LineString进行索引,但不能同时对两者进行索引...

如何在Opa中正确地进行GeoJSON数据的地理空间嵌入?它的DB接口和类型系统是可能的,还是限制太多了?非常感谢您的帮助和建议!

EN

回答 1

Stack Overflow用户

发布于 2013-09-20 20:10:06

似乎MongoDB允许创建两个地理空间索引并分别使用它们,但不能在同一查询中同时使用它们。

考虑一下示例输入数据:

代码语言:javascript
复制
db.geo.insert({location: {Point: {type: "Point", coordinates: [15,15]}}});
db.geo.insert({location: {LineString: {type: "LineString", coordinates: [[12,12],[13,13]]}}});
db.geo.insert({location: {Point: {type: "Point", coordinates: [55,55]}}});
db.geo.insert({location: {LineString: {type: "LineString", coordinates: [[52,52],[53,53]]}}});

和索引:

代码语言:javascript
复制
db.geo.ensureIndex({"location.Point": "2dsphere"});
db.geo.ensureIndex({"location.LineString": "2dsphere"});

location字段的地理空间查询:

代码语言:javascript
复制
db.geo.find({"location": {$geoWithin: {$geometry: {type: "Polygon", coordinates: [[[10,10],[10,20],[20,20],[20,10],[10,10]]]}}}});

给出正确的结果,但不使用索引:(

幸运的是,查询location.Pointlocation.LineString都使用索引:

代码语言:javascript
复制
> [...].explain()
{
    "cursor" : "S2Cursor",
    "isMultiKey" : true,
    "n" : 1,
    "nscannedObjects" : 1,
    [...]
    "matchTested" : NumberLong(1),
    "geoTested" : NumberLong(1),
    "cellsInCover" : NumberLong(25),
    [...]
}

不幸的是,Mongo不允许使用{$or: [subquery1, subquery2]}进行“特殊”查询……因此,这并不容易解决问题,但它可以在应用程序级别解决。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18902253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档