如何在Meteor / Minimongo中提高过滤器的响应能力

时间:2013-12-09 17:53:50

标签: mongodb meteor

我对Meteor很新。我的应用程序具有相当小的数据集,< 1000条记录,我构建了一个相当天真的过滤器即用型实现。

现在,性能非常糟糕 - 每个按键都会导致浏览器在相对较快的计算机上遵守冻结一两秒。

它目前已启用autopublish并且正在客户端执行所有操作,我知道这是问题的一个重要部分,我只是不确定如何改进它。

这是相关的代码段:

  Template.results.codes = function () {
    var query = Session.get("query")
    // todo: figure out if there's a better way to do this
    var search = (query && query.length > 3) ? {$where: function() {
        return this.code.indexOf(query) != -1;
    }} : {}
    return Codes.find(search);
  };

您可以在https://github.com/nfriedly/Meteor-ODB-II查看完整来源,然后在http://odb-ii.meteor.com/

进行试用

我有具体问题:

  • 有没有更好的方法来搜索mongo db / minimongo?
  • 是否有直接的方法将搜索移出UI线程?要么是网络工作者,要么只是在服务器上运行它?
  • 我的模板是否有办法知道“数据仍在加载”与“此集合中没有数据”之间的区别,以便在应用程序出现时不会闪现“找不到结果”消息最初加载。

4 个答案:

答案 0 :(得分:5)

欢迎来到流星!如果这是一个生产应用程序,我的第一个评论是你不应该使用自动发布 - 尤其不是1k记录。正确的方法是使用更复杂的分页框架。除此之外,我们可以通过一些调整使您当前的UI更快:

  1. 您可以使用mongo的regexp运算符,它似乎比使用where快得多。这本身就是一个巨大的胜利。
  2. isMatch调用codes这是一个非常大的性能影响因为它重新运行已经很昂贵的查询两次。相反,我们可以用会话变量替换此调用。
  3. 直接列出所有1k代码似乎有点傻。我在我的代码中将它限制为100,但在生产应用程序中我再次使用分页。
  4. 我将必要的查询长度减少到> 1,这似乎仍然很快。但你应该调整味道。
  5. 以下是我的更改:

    Template.results.codes = function () {
      var query = Session.get('query');
      var cursor = query && query.length > 1 ? Codes.find({code: new RegExp(query)}) : Codes.find({}, {limit: 100});
      Session.set('isMatch', cursor.count() > 0);
      return cursor;
    };
    
    Template.results.isMatch = function() {
      return Session.get('isMatch');
    };
    

    以下是运行meteor remove autopublish后如何使其工作的快速示例。

    向您的客户添加订阅:

    Tracker.autorun(function() {
      Meteor.subscribe('codes', Session.get('query'));
    });
    

    向您的服务器添加发布:

    Meteor.publish('codes', function(query) {
      if (query && query.length > 1) {
        return Codes.find({code: new RegExp(query)});
      } else {
        return Codes.find({}, {limit: 100});
      }
    });
    

    然后,您可以从limit功能中删除Template.results.codes。在发布中,我认为您需要以聪明的方式调整limitsquery.length的使用,但这应该让您开始。我希望有所帮助!

答案 1 :(得分:1)

您可以做的最重要的事情之一是优化您为过滤式搜索而发布的集合。使用自动发布不是一个选项。

Here是使用超过80,000个单词的字典的示例实现。 Here's the source.

对于'加载'效果,我会使用Iron-Router的waitOn方法,链接也会在评论中

答案 2 :(得分:0)

我同意“正则表达式”运算符是一个很好的方法。只要确保你适当地处理“特殊字符”。例如,您希望允许您的用户在未经验证的情况下将“*”(星号)等通配符传递给mongo,还是应该将其视为文字?

答案 3 :(得分:0)

我为此目的创建了一个autocomplete package,它支持过滤客户端和服务器端集合。它以Meteor的集合和反应性为基础,而不是像typeahead这样的基于数组的方法。

它使用了此线程中的大多数建议,即使对于1000个记录的集合,它在客户端上也相当快,并且可以使用服务器上的索引对于大型集合更快。