优化GeoJSON MongoDB查询

时间:2015-02-02 11:31:57

标签: mongodb geojson mongoengine

我的mongoDB中有一些存储在GeoJSON中的多边形。

客户端发送要加载的框列表(框是常规网格的单元格)。

检索它们的常规方法是使用每个框进行GeoJSON查询,但是当我有很多框时它很慢。

我不想检索重复项(位于两个单元格上的多边形被返回两次),因此我在下一个查询中列出了检索到的多边形 pks 以忽略它们。

假设:

box = [ [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 0, 1 ], [ 0, 0 ] ] ]  // the box to load
pks = [ ObjectId("54cf535cfe022e01ab4932f5"), ObjectId("54cf535cfe022e01ab4932f6") ] // the list of polygons already retrieved

使用mongoDB我会有这样的事情:

for box in boxes:
    db.places.find( { points: 
        { $geoIntersects: { $geometry: { type: "Polygon" ,  coordinates: box } } },
        { _id: { $nin: pks } } 
    } )

我使用MongoEngine,所以我有以下内容:

pks = []
for box in boxes:
   p = Polygon.objects(points__geo_intersects=box, pk__nin=pks)
   if len(p)>0:       
      pks += p.scalar("id")

我有三个问题:

1。使用此方法查询多边形是否有更有效的方法?

2。使用包含位于单元格上的多边形引用列表的Cell对象会更快吗?

在MongoEngine中我会有以下模型:

class Cell(Document):
    x = DecimalField()
    y = DecimalField()
    polygons = ListField(ReferenceField('Polygon'))

    meta = {
        'indexes': [[ ("x", 1), ("y", 1) ]]
    }

要加载的框列表将是与要加载的单元格对应的坐标。

这将与MongoEngine一起提供:

polygons = {}

for b in boxes:
    cell = Cell.objects.get(x=b['x'], y=b['y'])

    for polygon in cell.polygons:
        if not polygons.has_key(polygon.pk):
            polygons[polygon.pk] = polygon.to_json()

第3。是否有更有效的方法使用此方法查询多边形?(我认为我应该使用select_related(),也许可以直接在mongoDB查询中过滤多边形以避免检索重复项)< / p>

1 个答案:

答案 0 :(得分:0)

在做了几个基准之后,我可以回答我自己的问题:使用Cell等中间对象的速度明显加快。

但是,在查询中使用主键列表,如下所示:

pks = []
for box in boxes:
   p = Polygon.objects(points__geo_intersects=box, pk__nin=pks)
   if len(p)>0:       
      pks += p.scalar("id")

比使用字典忽略重复项慢得多,如下所示:

polygons = {}
for box in boxes:
   p = Polygon.objects(points__geo_intersects=box)
   for polygon in p:
      if not polygons.has_key(polygon.pk):
          polygons[polygon.pk] = polygon.to_json()