我有多个正在进行的订阅,用于描述数据和该数据的每用户状态。最终,这会显示在Google地图上。
我们称之为:
shops
- 商店ID,名称和位置列表。此集使用当前映射边界作为返回数据的限制。rating
- 每个用户对此商店的评分。目前,无论商店是否在视线内,都会退回所有评级。这些订阅中的每一个当前都在其自己的Tracker.autorun
块中运行。这是有效的,但如果商店的数量超过给定的限制,坏事就会发生。这里的坏事是DDP以某种方式超时,重新同步开始,超时,重新同步...永远。
请不要建议在Google地图上添加20,000个标记是一个坏主意。我知道这一点,但无论如何我想在这个发展阶段都这样做。
糟糕的方法:
最初,我在shops
的游标观察者中创建了标记,如果商店有评级,我会调用findOne()来查找。这很难扩展,因为MiniMongo没有索引,因此成为rating
集合中的线性搜索。
First Refine:
我后来将shops
添加到地图作为第二阶段。如果订阅已经完全准备好,我执行find()并在那里添加商店。这主要起作用。它阻止了DDP超时,但仍然需要很长时间来处理商店数据,内部findOne()调用仍然是线性的。
Second Refine:
我已加载shops
的所有数据后才订阅ratings
。这是一个小小的改变,但实际上确实略微改善了性能。我怀疑是因为先前已加载shops
,然后填充ratings
时,必须更新标记。防止这种双重更新使事情变得更好。
潜在的第三次优化:
此计划允许使用两个集合游标的添加,更改和删除的回调实时加载内容。但是,我不是使用findOne()来检查评级,而是使用ratings
回调来填充具有商店ID的对象,如果存在标记,则更新它。然后,商店添加标记和更新标记代码引用此对象。 E.g:
@ratings = {}
recordRating: (id, rating) ->
@ratings[id] = rating
@updateMarker(id)
removeRating: (id) ->
delete @ratings[id]
@updateMarker(id)
重构这一点需要做一些工作。在我采取行动之前,还有更好的方法吗?是否有一个Meteor软件包可以帮助解决我刚才找不到的问题?