2014-05-12 87 views
0

我有一個json,其中包含代表一個國家/地區所有城市(共78個)的分隔符的多邊形。例如:在MongoDB中按多邊形分組

{ 
    "City1":[ 
     [-67.103276,18.513426], 
     [-67.10339411502086,18.514532657212502], 
     [-67.093752,18.515757], 
     [-67.05297606966441,18.512073045833525] 
    ], 
    "City2":[ 
     [-67.16901339052771,18.472154288860388], 
     [-67.169016,18.478488], 
     [-67.138249,18.507776], 
     [-67.12906260088943,18.510642646697203], 
     [-67.125655,18.511706] 
    ], 
    "City3":[ 
     [-66.034932,18.333452], 
     [-66.03494,18.332214], 
     [-66.035911,18.328084], 
     [-66.035731,18.31961], 
     [-66.036859,18.318627] 
    ], 
    ... 
} 

我爲MongoDB使用了ruby驅動程序。數據庫包含一組點(索引爲2dsphere)。我需要計算一個城市內的積分總數。結果應該說,例如,「城市1包含56分,城市2包含40分,城市3包含100分」。

這是代碼,我使用的是找到一個多邊形內部的點,並設置日期範圍FROM_DATE至END_DATE(因爲點有個約會屬性)

polygon = [[-67.103276,18.513426],[-67.10339411502086,18.514532657212502],[-67.093752,18.515757],[-67.05297606966441,18.512073045833525]] 
from_date = DateTime.strptime(params[:from_date], '%Y-%m-%d') 
from_date = Time.utc(from_date.year, from_date.month, from_date.day) 
to_date = DateTime.strptime(params[:to_date], '%Y-%m-%d') 
to_date = Time.utc(to_date.year, to_date.month, to_date.day) 

@coll = db.collection("points") 
recordset = @coll.find(
    { 
     "$and" => [ 
      { "geometry.coordinates" => { 
       "$within" => {"$polygon" => polygon} 
      }}, 
      { "properties.time" => { 
       :$gte => from_date, 
       :$lte => to_date 
      }} 
     ] 
    }, 
    :fields => { :_id => false } 
) 

有沒有什麼辦法,我可以用一個查詢將所有城市的結果分組,或者我必須查詢數據庫78次以獲得每個城市的數量?

回答

0

當您想要group時,您需要使用aggregation framework。您將需要兩個步驟聚合管道和一個可選的第三步:

  1. $match運營商(順便說一下上面的查詢:在$是不必要的,你可以把"geometry.coordinates""properties.time"同一關聯數組英寸)
  2. a $group運營商,其中_id => "$cityname"(我猜城市名稱是存儲城市名稱的字段)和"number_of_points" => { "$sum" => 1 }。新字段number_of_points將包含每個城市的點數。
  3. (可選)城市名稱現在位於_id字段中。當您希望該字段具有不同的名稱時,可以使用額外的$project步驟對其進行重命名。
+0

其實集合中的點並不是由城市名稱標識的,它們只有座標。您是否認爲在插入之前對每個點進行地理編碼以瞭解它們屬於哪個城市會更好,然後爲每個點添加城市名稱字段,以便我可以按城市名稱進行分組?或者有一種方法可以按多邊形分組(避免添加城市名稱字段)?這是一個高流量的網站,所以表現是一個問題。 – rcrivera

+0

@rcrivera這取決於你的**精確**使用模式,但是當你需要計算每個點的城市不止一次(平均),然後在插入時確定每個點的城市一定會是更有效的解決方案。這假設你的城市限制不會經常改變(比點更頻繁),因爲當城市限制改變時,所有點都需要重新評估。 – Philipp