2014-05-12 48 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