【问题标题】:meteorjs subscribe usage when collection is huge当收集量很大时,meteorjs 订阅使用情况
【发布时间】:2014-05-12 23:03:34
【问题描述】:

我不知道使用meteorjs 处理庞大的mongo 数据库的最佳方法。

在我的示例中,我有一个数据库集合,其中包含地址和地理位置。 (整个代码sn-ps只是例子)

例子:

{
   address : 'Some Street',
   geoData : [lat, long]
}

现在我有一个表单,用户可以在其中输入地址以获取地理数据。很简单。但问题是,包含地理数据的集合中包含数百万个文档。

在 Meteor 中,您必须在服务器端发布集合并在客户端和服务器端订阅。所以我的代码是这样的:

// Client / Server

Geodata = new Meteor.collection('geodata');

// Server side
Meteor.publish('geodata', function(){
  return Geodata.find();
});

// Client / Server
Meteor.subscribe('geodata');

现在有人填写了表格 - 之后我得到了数据。在此之后,我搜索要返回的正确文档。我的方法是这样的:

// Server / Client
Meteor.methods({
 getGeoData : function (address) {
    return Geodata.find({address : address});
 }
});

结果是正确的。这仍然有效。但我现在的问题是:

在我的示例中使用庞大的数据库处理此示例的最佳方法是什么?问题是当我订阅 Meteor 时,它会将整个集合保存在用户缓存中。有没有办法只订阅我需要的结果,当用户重用表单时,我可以覆盖订阅?还是有另一种好方法来保存大型数据库的性能以及我在示例中使用它的方式?

有什么想法吗?

【问题讨论】:

    标签: javascript mongodb collections meteor


    【解决方案1】:

    是的,你可以这样做:

    // client
    Deps.autorun(function () {
      // will re subscribe every the 'center' session changes
      Meteor.subscribe("locations", Session.get('center'));
    });
    
    // server
    Meteor.publish('locations', function (centerPoint) {
      // sanitize the input
      check(centerPoint, { lat: Number, lng: Number });
      // return a limited number of documents, relevant to our app
      return Locations.find({ $near: centerPoint, $maxDistance: 500 }, { limit: 50 });
    });
    

    您的客户当时只会要求提供部分数据。即你大部分时间不需要整个集合,通常你需要一些特定的子集。您可以要求服务器仅让您了解该特定子集的最新信息。请记住,您的客户端发出的不同“发布请求”越多,您的服务器要做的工作就越多,但这就是通常的完成方式(这里是简化版本)。

    请注意我们如何订阅Deps.autorun 块,该块将根据center Session 变量(反应式)重新订阅。因此,您的客户可以通过更改此变量来检查不同的数据子集。

    【讨论】:

      【解决方案2】:

      当将整个集合发送到客户端没有意义时,您可以使用方法从服务器检索数据。

      在您的情况下,您可以在填写表单时调用getGeoData 函数,然后在方法返回后显示结果。尝试采取以下步骤:

      1. 如果您还没有,请将您的客户端和服务器代码清楚地划分到各自的 clientserver 目录中。
      2. 删除服务器上的geodata订阅(只有客户端可以激活订阅)。
      3. 删除服务器上的geodata 发布(假设不再需要)。
      4. 仅在服务器上定义getGeoData 方法。它应该返回一个对象,而不是游标,因此请使用 findOne 而不是 find
      5. 在表单的 submit 事件中,执行以下操作:
      Meteor.call('getGeoData', address, function(err, geoData){Session.set('geoDataResult', geoData)});
      

      然后您可以在模板中显示geoDataResult 数据。

      【讨论】:

      • 至第 2 点:这是我的示例中的错误。在我目前的脚本中,我只是将它放在客户端。我会检查其余的并在此之后评论您的想法!感谢您的快速响应。
      • 我喜欢这种方法,因为您不需要反应性(地址地理编码不会不断变化),从性能角度来看,Meteor.method 是最好的。
      猜你喜欢
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多