2015-02-02 2 views
0

내 mongoDB의 GeoJSON에 저장된 폴리곤이 있습니다.GeoJSON MongoDB 쿼리 최적화

클라이언트가로드 할 상자 목록을 보냅니다. 상자는 일반 격자의 셀입니다.

그들을 검색하는 일반적인 방법은 각 상자에 GeoJSON 쿼리를 만드는 것이지만 상자가 많으면 느립니다.

두 개의 셀에있는 다각형이 두 번 반환됩니다. 따라서 검색된 다각형의 목록을 만듭니다. pks 다음 쿼리에서이를 무시할 수 있습니다.

을 감안할 때 : MongoDB를 가진

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 

나는이 같은 것이다 : 나는 MongoEngine를 사용

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

을, 그래서 나는 다음과 같습니다

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. 셀에있는 다각형 참조 목록이 포함 된 셀 개체를 사용하는 것이 더 빠릅니까? 로드 셀에 해당하는 좌표가 될 것입니다로드 상자의

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

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

목록 :

는 MongoEngine에서 나는 다음과 같은 모델을 가지고있다. 이 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 쿼리에서 직접 다각형을 필터링하는 것이 가능할 수도 있습니다)

+0

가 난 그냥했다 :

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

은 다음과 같이 중복을 무시하는 사전을 사용하는 것보다 훨씬 느립니다 벤치 마크 : 첫 번째 방법에서는 폴리곤을 검색하는 데 2.03 초가 걸리고 두 번째 방법에서는 0.65 초가 걸렸습니다. –

+0

Hum ... 사실 나는 그 차이가 아마도'pk__nin = pks'에서 나왔음을 알게되었습니다. 이제 첫 번째 방법으로 더 빠른 결과를 얻었습니다 ... 점심 식사 후에 더 조사 할 것입니다 ... –

답변

0

몇 가지 벤치 마크를 작성한 후, 필자 만의 질문에 답할 수 있습니다. Cell과 같은 중간 개체를 사용합니다. 이 같은 쿼리에서 기본 키의 목록을 사용하지만

, :

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()