在 Meteor 中,如何只查询给定订阅的记录?

Posted

技术标签:

【中文标题】在 Meteor 中,如何只查询给定订阅的记录?【英文标题】:In Meteor, how can I query only the records of a given subscription? 【发布时间】:2015-03-01 03:15:18 【问题描述】:

我了解订阅是将记录从this post 和其他人流到客户端集合的一种方式...

但是,根据this post,您可以有多个订阅流入同一个集合。

// server
Meteor.publish('posts-current-user', function publishFunction() 
  return BlogPosts.find(author: this.userId, sort: date: -1, limit: 10);
  // this.userId is provided by Meteor - http://docs.meteor.com/#publish_userId

Meteor.publish('posts-by-user', function publishFunction(who) 
  return BlogPosts.find(authorId: who._id, sort: date: -1, limit: 10);


// client
Meteor.subscribe('posts-current-user');
Meteor.subscribe('posts-by-user', someUser);

现在 - 我通过两个不同的订阅获取了我的记录,我可以使用订阅获取它撤回的记录吗?还是我必须重新查询我的收藏?在客户端和服务器之间共享该查询的最佳做法是什么?

我希望我在这里没有遗漏一些明显的东西,但是仅因为它的副作用而执行Meteor.subscribe 函数似乎丢失了一条非常有用的信息——即一条记录来自哪个订阅。大概选择发布和订阅的名称是有意义的 - 如果我能找到与该名称相关联的记录,那就太好了。

【问题讨论】:

how to know which docs are sent to the client in meteor的可能重复 查看我对上述问题的评论。您可能需要进行转换以标记哪些文档来自哪个发布者。一般来说,如果这确实是一个问题,那感觉就像一个“你做错了”的问题。您能否详细解释一下为什么这在您的用例中很重要? Meteor publish/subscribe strategies for unique client-side collections的可能重复 【参考方案1】:

您似乎想要做的是维护两个单独的记录集合,其中每个集合都由不同的出版物填充。如果您阅读DDP specification,您会看到服务器告诉客户端每条记录属于哪个集合(而不是发布),并且多个发布实际上可以为同一记录提供不同的字段

但是,Meteor 实际上允许您将记录发送到任意集合名称,客户端将查看它是否具有该集合。例如:

if (Meteor.isServer) 
  Posts = new Mongo.Collection('posts');


if (Meteor.isClient) 
  MyPosts = new MongoCollection('my-posts');
  OtherPosts = new MongoCollection('other-posts');


if (Meteor.isServer) 
  Meteor.publish('my-posts', function() 
    if (!this.userId) throw new Meteor.Error();

    Mongo.Collection._publishCursor(Posts.find(
      userId: this.UserId
    ), this, 'my-posts');

    this.ready();
  );

  Meteor.publish('other-posts', function() 
    Mongo.Collection._publishCursor(Posts.find(
      userId: 
        $ne: this.userId
      
    ), this, 'other-posts');

    this.ready();
  );


if (Meteor.isClient) 
  Meteor.subscribe('my-posts', function() 
    console.log(MyPosts.find().count());
  );

  Meteor.subscribe('other-posts', function() 
    console.log(OtherPosts.find().count());
  );

【讨论】:

非常感谢。它帮助我们在客户端进行适当的搜索。很有帮助的答案!【参考方案2】:

这是正在发生的事情:

假设您的服务器端 BlogPosts Mongo 集合包含来自 10 个不同用户的 500 个帖子。然后,您在客户端订阅了两个不同的订阅:

Meteor.subscribe('posts-current-user'); // say that this has 50 documents
Meteor.subscribe('posts-by-user', someUser); // say that this has 100 documents

Meteor 将看到 Meteor.subscribe('posts-current-user'); 并继续将当前用户的帖子下载到客户端 Mini-Mongo 的 BlogPosts 集合。

Meteor 然后会看到Meteor.subscribe('posts-by-user', someUser); 并继续将someuser 的帖子下载到客户端Mini-Mongo 的BlogPosts 集合中。

所以现在客户端 Mini-Mongo BlogPosts 集合有 150 个文档,这是 server-side BlogPosts 集合中全部 500 个文档的子集。

因此,如果您在客户端(Chrome 控制台)中执行 BlogPosts.find().fetch().count,则结果将是 150

【讨论】:

我认为问题出在客户端上,您如何仅获取用户发布的帖子?我认为你的答案没有那么远。我相信您会在客户端使用与服务器上发布的相同查询进行查找。【参考方案3】:

当然!这仅取决于您在哪里编写订阅。在很多情况下,您可能正在使用 Iron Router,在这种情况下,您将有一个给定的路由订阅您需要的数据。然后在该路由模板的助手中,您只能查询该订阅中的文档。

但总体思路是,您将特定订阅连接到特定模板。

Template.onePost.helpers(
  post: function() 
    Meteor.subscribe('just-one-post', <id of post>);
    return Posts.findOne();
  
);

Template.allPosts.helpers(
  posts: function() 
    Meteor.subscribe('all-posts');
    return Posts.find();
  
));

【讨论】:

铁制路由器外壳听起来很有趣,我会尝试一下。我不确定订阅助手是否会让我感到满意,因为我不太清楚这些订阅何时会停止。

以上是关于在 Meteor 中,如何只查询给定订阅的记录?的主要内容,如果未能解决你的问题,请参考以下文章

Meteor 发布/订阅独特客户端集合的策略

带有 Meteor 的 Blaze-Apollo,观察者不会触发变量更改的订阅

Angular2-meteor - 在订阅函数中使用排序的 find() 后未定义的变量

在 Meteor 中访问订阅的问题

Meteor 应用程序:初始加载 >1 分钟,7.4M,800 个请求

Meteor、MongoDB通过订阅获取部分数组