MongoDB优化聚合

时间:2017-09-09 20:34:30

标签: mongodb optimization match lookup aggregation

我几天前在我的计算机上安装了MongoDB来为一项工作做一些测试,详细地说我们必须将大量数据从基于Postgres的系统传输到MongoDB系统。 因为我们不知道MongoDB(我们第一次使用它),我们尝试研究文档,我们在一个小数据库上做了一些测试,只有很少的数据来测试性能...... 经过多次测试,我们仍然在恶化...... 但是现在我将解释上下文,所以也许有人可以告诉我,如果我们做错了什么。 我们知道哪些是更“有问题”的查询,我会在这里写一个,在Postgres中,查询是这样的(我会减少不必要的):

selectStmt varchar = 'SELECT station.radarmeteo_id,
  date(datetime_range) AS datetime_range,
  district.name AS district,
  city.name AS city,
  min_temperature::real / 10::real,
  max_temperature::real / 10::real,
  rainfall_daily::real / 10::real,
  max_wind_speed::real / 10::real,
  extract(epoch FROM datetime_range) as unix_datetime ';

fromStmt varchar = ' FROM measurement_daily
  INNER JOIN station ON measurement_daily.station_id = station.id;

在MongoDB中我们写了这个:

db.measurement_daily.aggregate([{"$match":{"min_temperature":{"$gt":random.randint(-30, 14), "$lt":random.randint(18, 50)}}},{"$lookup":{"from":"station","localField":"station_id", "foreignField":"_id", "as": "scd"}},{"$unwind":"$scd"},{"$project":{"_id":1,"min_temperature":1,"max_temperature":1, "rainfall_daily":1, "max_wind_speed":1, "radarmeteo_id":"$scd.radarmeteo_id", "city_name":"$scd.city_name", "district_name":"$scd.district_name"}},{"$out":"result"}])

我在这里要问的是:它应该写得更好?或者可以有更好的方法来获得相同的结果?我们可以使用其他任何优化吗? 我们需要最佳的响应时间,因为真正的数据库应该只有200.000.000的数据才能在这个集合中... 就在这里有2个表分别有1000个(站)和6400个(measurement_daily)记录/文件,我们有3,5-4s(Postgres)和30-32s(MongoDB)作为响应时间...... (为了测试两个系统中的性能,查询重复200次(这就是为什么我们分别有一个查询需要3,5-4s和30-32s),以便具有“同质”响应时间,以最大限度地减少外部原因的调节。) 任何帮助都非常感谢...

1 个答案:

答案 0 :(得分:1)

根据mongoDB documentation当$ unwind紧跟在另一个$ lookup之后,$ unwind在$ lookup的as字段上运行时,优化器可以将$ unwind合并到$ lookup阶段。这样可以避免创建大型中间文档。

在您的情况下,它将如下所示:

"$lookup": {
     "from":"station",
     "localField":"station_id", 
     "foreignField":"_id", 
     "as": "scd"
     unwinding: { preserveNullAndEmptyArrays: false }
 }