当集合巨大时,meteorjs订阅使用

时间:2014-04-01 22:41:38

标签: javascript mongodb collections meteor

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

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

示例:

{
   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在订阅时将整个集合保存在用户缓存中。有没有办法订阅我需要的结果,当用户重用表单时,我可以覆盖订阅?或者是否有另一种利用大型数据库保存性能的好方法以及我在示例中使用它的方式?

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

是的,你可以这样做:

// 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会话变量(被动)重新订阅。因此,您的客户可以通过更改此变量来检查不同的数据子集。

答案 1 :(得分:1)

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

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

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

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