有没有办法告诉 Meteor 一个集合是静态的(永远不会改变)?

6
在我的Meteor项目中,用户可以发布活动,必须通过自动完成选择活动所在的城市。我有一个完整的法国城市列表,并且它永远不会更新。
我想使用基于集合和发布-订阅的方法来处理自动完成输入,因为我不希望客户端下载完整数据库(5MB)。为了提高性能,有没有一种方法告诉Meteor这个集合是“静态”的?还是说没有区别?
是否有人能提出不同的方法?
3个回答

7
当你“想要告诉服务器一个集合是静态的”时,我知道有两种潜在的优化方法:
1. 不使用实时查询来观察数据库,因为数据永远不会改变。 2. 不将此查询的结果存储在merge box中,因为它不需要被跟踪和与其他数据进行比较(节省内存和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 引用的集合名称相同,也可能不同。请注意,您可以通过发布做 许多其他事情(另请参见上面的链接)。 更新:为解决第二个问题可能非常棘手,具体取决于集合的大小,有必要完全绕过 Meteor。参见 https://dev59.com/Umcs5IYBdhLWcg3wHwbU#21835534 以了解一种方法。另一种方法是将 fetch() 的集合作为方法调用返回,尽管这没有压缩的好处。

1
直到第二个问题解决之前,这应该是可接受的答案。感谢Andrew。 - Wes Johnson
1
@WesJohnson 参见 https://dev59.com/Umcs5IYBdhLWcg3wHwbU#21835534 了解如何解决问题#2。我也会在某个时候更新这个答案。 - Andrew Mao

3

来自Meteor文档:

"对集合所做的任何更改都将触发重新计算,包括更改游标中的文档。如要禁用此行为,请将{ reactive: false }作为选项传递给find()方法."

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


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}});
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接