如何用动态组优化慢速Mongo MapReduce



我刚开始使用mongo,但对关系数据库有丰富的经验。

我有大约85000个事件托管在位置,每个事件都有一个相关的权重。对于热图,我现在需要对纬度/经度区域内事件的累积权重进行分组。

mongo中,它目前看起来是这样的(没有索引,尝试了没有成功):

events: {
  latitude: Number,
  longitude: Number,
  weight: Number
}
db.events.mapReduce(function() {
    emit({
      latitudeGroup: Math.floor(this.latitude / 1.2),
      longitudeGroup: Math.floor(this.longitude / 1.8)
    }, this.weight);
  }, function(key, values) {
    return Array.sum(values)
  }, { out: 'inline' })
请注意,1.2和1.8是任意的和动态的,缓存每个可能的组合的结果将非常消耗内存。查询需要1500ms,这对于实时web应用程序来说太长了。

来自关系世界,我在Postgres:

中尝试了同样的方法。
CREATE TABLE event (
  id BIGSERIAL NOT NULL PRIMARY KEY,
  latitude NUMERIC NOT NULL,
  longitude NUMERIC NOT NULL,
  weight INTEGER NOT NULL
);
SELECT floor(latitude / 1.2) AS latitudeGroup, floor(longitude / 1.8) AS longitudeGroup, SUM(weight) FROM event GROUP BY latitudeGroup, longitudeGroup;

这需要一个更可接受的400ms,而不使用任何Postgres的GiST功能。

我只是想知道我是否错过了一些关于蒙古的东西。我已经研究了聚合框架,但不认为我正在做的是可能的。

我将非常高兴,如果有一些方法使这个工作与合理的性能。这是我正在开发的原型的一个关键功能,在这个阶段,数据库切换不会太昂贵。

首先,您应该使用index进行测试。

您是否也尝试过使用聚合框架而不是MapReduce?

db.events.aggregate([
  { $group : {
  _id : { "latitude" : "$latitude", "longitude" : "$longitude" } ,   
      weight : { "$sum" : { $multiply : ["$weight",1.2]} }
  }}
])

聚合框架使用与数据库核心查询引擎相同的机制(不像使用V8引擎的MapReduce)

你可以试试下面的方法,看看是否有效。

db.events.aggregate([
  { $project : {
    weight:1,
    lat: {$divide:["$latitude",1.2]},
    long: {$divide:["$longitude",1.8]}
  }},
  { $group : {
  _id : { "lat" : "$lat", "long" : "$long" } ,   
  weight : { "$sum" : "$weight"} }
  }}
])

相关内容

  • 没有找到相关文章

最新更新