1

我正在使用 Meteor.js 开发过滤后的实时搜索模块。

用例和问题:

用户想要通过所有用户进行搜索以找到朋友。但是我不能让每个用户都询问完整的用户集合。用户使用复选框过滤搜索。我想订阅匹配的用户。最好的方法是什么?

我想创建查询客户端会更好,然后将方法发送给它以取回所需的用户集。但是,我想知道:当过滤条件发生变化时,新订阅是否会清除所有旧订阅?因为,如果我进行第一次搜索返回 me [usr1, usr3, usr5],然后搜索返回 me [usr2, usr4],最好保留第一个集合,并在客户端订阅的集合中简单地添加新的集合。

而且,此外,如果我做第三次研究应该返回我 [usr1, usr3, usr2, usr4],自动运行的订阅不会向我发送任何东西,因为我的集合中已经有整个结果集。

目标是节省来自服务器的处理和数据传输。

我有一些想法,但我还没有编写足够的代码,无法以一种简单全面的方式分享它。

您如何建议我在节省时间和节省性能方面做得更相关?

谢谢大家。

大卫

4

2 回答 2

1

这取决于您的应用程序,但您可能会向发布者发送一个非空字符串,发布者使用该字符串在用户集合中搜索匹配的名称。例如:

Meteor.publish('usersByName', function(search) {
  check(search, String);

  // make sure the user is logged in and that search is sufficiently long
  if (!(this.userId && search.length > 2))
    return [];

  // search by case insensitive regular expression
  var selector = {username: new RegExp(search, 'i')};

  // only publish the necessary fields
  var options = {fields: {username: 1}};

  return Meteor.users.find(selector, options);
});

另请参阅为什么我们限制字段的常见错误

表现

Meteor 足够聪明,可以跟踪每个客户为每个发布者拥有的当前文档集。当发布者重新运行时,它知道只发送集合之间的差异。所以你上面描述的情况已经为你处理好了。

  1. 如果您订阅了用户:1,2,3
  2. 然后您重新启动了用户 2、3、4 的订阅
  3. 服务器将为removed1 发送一条消息,为 4 发送一条添加消息。

请注意,如果您在重新运行订阅之前停止订阅,则不会发生这种情况。


removed据我所知,在修改单个订阅的参数时没有办法避免消息。我可以想到两种可能(但很棘手)的替代方案:

  1. 累积所有先前搜索查询的交集并在订阅时使用它。例如,如果用户搜索{height: 5}然后搜索{eyes: 'blue'}您,则可以使用 订阅{height: 5, eyes: 'blue'}。这可能很难在客户端上实现,但它应该以最少的网络流量完成您想要的。

  2. 累积活跃订阅。而不是每次用户修改搜索时都修改现有订阅,而是为新的文档集启动新订阅,并将订阅句柄推送到数组。当模板被销毁时,您需要遍历所有句柄并调用stop()它们。这应该可行,但会消耗更多资源(网络和服务器内存+ CPU)。

在尝试这些解决方案之前,我建议在不使用它们的情况下对最坏的情况进行基准测试。我主要担心的是,如果没有相当严格的控制,您最终可能会在连续搜索后发布整个用户集合。

于 2015-05-29T21:51:19.637 回答
0

如果您想在服务器上轻松一点,您将希望向客户端发送尽可能少的数据。这意味着您发送给不是朋友的客户的每一份文件都是浪费。因此,让我们消除所有这些浪费。

收集您的过滤器(例如filters = {sex: 'Male', state: 'Oregon'})。然后根据您的过滤器调用一个方法进行搜索(例如Users.find(filters)。此外,您可以运行自己的专有排名算法来确定一个人是朋友的机会百分比。可能基于与 IP 地址的距离(或手机 GPS 历史记录) ), 共同的朋友等。这将在效率上有所回报。索引诸如 GPS 坐标或其他高度独特的属性之类的东西,也许可以尝试复合索引。但请记住,索引越多,写入速度就越慢。

现在您已经有了一个包含所有可能朋友的光标,从最有可能到最不可能排列。

接下来,更改您的订阅以匹配那些朋友,但limit:20在那里放一个。此外,只发送您需要的字段。这样,如果用户想跳过这一步,你只会浪费通过网络发送 20 个部分文档。然后,用户可以单击无限滚动或“加载更多”按钮。当他们加载更多时,这是一个附加订阅,因此它不会重新发送重复信息。Discover Meteor 非常详细地描述了这种模式,所以我不会。

几次点击/滚动后,用户将找不到更多朋友(因为您很聪明并对其进行了排序),因此他们将停止尝试并继续下一步。如果您返回了 200 个可能的朋友并且他们在 60 个之后停止尝试,那么您只需保存 140 个文档,使其免于通过管道。有你的效率。

于 2015-05-29T21:16:24.033 回答