简体   繁体   English

已发布集合的流星反应过滤

[英]Meteor reactive filtering of published collection

I have two collections Issues & Simulations: 我有两个集合《问题与模拟》:

// Issues
{
  issueId: 1000, 
  appears: '2014-01-01',
  ...
}
// Simulations
{
  history: [50,200,30], 
  date: '2014-01-01',
  ..
}

How to re-actively publish issues that are not in single simulation. 如何重新发布非单一模拟中的问题。

Meteor.publish('issues', function () {
    var simulation = Simulations.findOne({}),
        history = lodash.pluck(simulation.history, 'issueId');
    return Issues.find({
        issueId: {$nin: history},
        appears: {$lte: simulation.date}
    }, {limit: 12});
});

When I make changes to simulation either date or push issueIds into Simulation history I want published data to change. 当我更改模拟日期或将issueIds推送到模拟历史记录中时,我希望更改已发布的数据。 I found some package publish with relations but I have trouble understanding how to use it and is it what I really need. 我发现一些与关系有关的软件包已发布,但是我很难理解如何使用它,这是我真正需要的。 https://atmospherejs.com/cottz/publish-with-relations https://atmospherejs.com/cottz/publish-with-relations

Your publish function will not run reactively with respect to parameters. 您的发布功能将不会对参数做出反应。 What I mean by that is that once the cursor has been return by the publish function, changes to the record set returned by that query will be synchronised with the client, but changes to the query will not have any effect. 我的意思是,一旦publish函数返回了游标, 对该查询返回的记录集的更改将与客户端同步,但是对查询的更改将不起作用。 So if you were to add another document to the Issues collection that matches the original query {issueId: {$nin: originalHistory}, appears: {$lte: originalSimulation.date}} it will be sent to the client, but if you make a change to the Simulations collection it will have no effect as the cursor has already been returned by the publish function. 因此,如果您要向“ Issues集合中添加另一个与原始查询{issueId: {$nin: originalHistory}, appears: {$lte: originalSimulation.date}}匹配的文档{issueId: {$nin: originalHistory}, appears: {$lte: originalSimulation.date}} ,它将被发送给客户端,但是如果您这样做对Simulations集合的更改将无效,因为publish函数已经返回了光标。

One way of achieving what you are aiming for would be to subscribe to the publication within an autorun block, and pass reactive parameters which you can update as required. 实现目标的一种方法是在自动运行块中订阅发布,并传递可根据需要更新的反应性参数。 Keeping the subscription within an autorun block will not only make it rerun reactively, but it will automatically cancel old subscriptions so that you don't continually increase server load. 将订阅保留在自动运行块中,不仅会使它被动地重新运行,而且会自动取消旧的订阅,以免您不断增加服务器负载。 Something like this: 像这样:

server: 服务器:

Meteor.publish('issues', function (simulation, history) {
    return Issues.find({
        issueId: {$nin: history},
        appears: {$lte: simulation.date}
    }, {limit: 12});
});

client: 客户:

Tracker.autorun(function() {
    var simulation = Simulations.findOne({}),
        history = lodash.pluck(simulation.history, 'issueId');
    Meteor.subscribe('issues', simulation, history);
});

Note that there ARE ways you can achieve this solely on the server, by observing changes and utilising the low-level publications API. 请注意,有一些方法可以通过观察更改并利用低级发布API来完全在服务器上实现。 More about how you could do this here . 有关如何在此处执行此操作的更多信息。 It's almost certainly more complicated to do things that way, but there could be a performance benefit depending on how much computational capacity you have available on client and server, 用这种方法做事几乎肯定要复杂得多,但是可能会带来性能上的好处,具体取决于您在客户端和服务器上拥有多少计算能力,

I've tried @richsilv approach but in the end I've ended up using https://atmospherejs.com/mrt/reactive-publish I don't know is it the right approach but since it automagically works it will do for now. 我尝试了@richsilv方法,但最终我还是使用https://atmospherejs.com/mrt/reactive-publish,我不知道这是正确的方法,但是因为它可以自动工作,所以现在可以使用。

Meteor.reactivePublish('issues', function () {
    var simulation = Simulations.findOne({}, {reactive: true}),
        history = lodash.pluck(simulation.history, 'issueId');
    return Issues.find({
        issueId: {$nin: history},
        appears: {$lte: simulation.date}
    }, {limit: 12});
});

You can use the reactive-publish package (I am one of authors). 您可以使用react-publish包(我是作者之一)。 It is a rewrite of the package mentioned by @slobodan.blazeski: 它是对@ slobodan.blazeski提到的软件包的重写:

Meteor.publish('issues', function () {
    this.autorun(function (computation) {
        var simulation = Simulations.findOne({}, {fields: {history: 1, date: 1}}),
            history = lodash.pluck(simulation.history, 'issueId');
        return Issues.find({
            issueId: {$nin: history},
            appears: {$lte: simulation.date}
        }, {limit: 12});
    });
});

The important thing is that you limit the fields you are interested in the simulation document so that autorun does not unnecessarily rerun when some other fields change. 重要的是要限制对模拟文档感兴趣的字段,以便在某些其他字段发生更改时不会不必要地重新运行autorun运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM