6

在我的流星项目中,用户可以发布事件,他们必须(通过自动完成)选择将在哪个城市发生。我有一个完整的法国城市列表,它永远不会更新。

我想使用基于自动完成输入的集合和发布订阅,因为我不希望客户端下载完整的数据库(5MB)。对于性能,有没有办法告诉流星这个集合是“静态的”?还是没有区别?

有人可以提出不同的方法吗?

4

3 回答 3

7

当您“想告诉服务器集合是静态的”时,我知道两个潜在的优化:

  1. 不要使用实时查询来观察数据库,因为数据永远不会改变
  2. 不要将此查询的结果存储在合并框中,因为它不需要跟踪和与其他数据进行比较(节省内存和 CPU)

(1) 是您可以通过构建自己的发布光标轻松完成的事情。但是,如果任何客户端正在观察相同的查询,我相信 Meteor 会(至少在未来)对此进行优化,因此对于任意数量的客户端来说,它仍然只是一个实时查询。至于(2),我不知道有任何直接的方法可以做到这一点,因为它可能会破坏合并多个发布和订阅的数据。

为避免使用实时查询,您可以手动将数据添加到发布函数而不是返回游标,这会导致.observe()调用该函数以将数据连接到订阅。这是一个简单的例子:

Meteor.publish(function() {
    var sub = this;
    var args = {}; // what you're find()ing

    Foo.find(args).forEach(function(document) {
        sub.added("client_collection_name", document._id, document);
    });

    sub.ready();
});

这将导致数据被添加到client_collection_name客户端,它可能与 引用的集合具有相同的名称Foo,或者不同的名称。请注意,您可以使用出版物做许多其他事情(另请参阅上面的链接。)

更新:为了解决(2)中的问题,根据集合的大小,这可能是非常有问题的,有必要完全绕过 Meteor。有关执行此操作的一种方法,请参见https://stackoverflow.com/a/21835534/586086。另一种方法是仅将 collectionfetch()作为方法调用返回,尽管这没有压缩的好处。

于 2013-09-23T01:25:01.360 回答
3

来自 Meteor doc :“对集合的任何更改都会更改游标中的文档将触发重新计算。要禁用此行为,请将 {reactive: false} 作为查找选项传递。”

我认为这个简单的选项是最好的答案

于 2013-10-10T08:25:28.420 回答
0

你不需要发布你的整个收藏。
1.仅在用户输入前 3 个字母后才显示自动完成选项 - 这将显着缩小您的搜索范围。
2.提供不超过 5-10 个城市作为选项 - 这将使您的记录集非常小 - 因此无需向每个用户推送 5mb 的数据。
您的出版物应如下所示:

Meteor.publish('pub-name', function(userInput){
   var firstLetters = new RegExp('^' + userInput);
   return Cities.find({name:firstLetters},{limit:10,sort:{name:1}});
});
于 2015-07-25T22:44:25.720 回答