在 meteor 中发布虚拟 collection

Publish a virtual collection in meteor

我正在尝试使用 2 个不同的名称发布 collection。 freeCourses 包含没有 paid_url 字段的课程。 premiumCourses 包含 id 存在于 userCourses collection.

中的所有课程

用户课程collection: { user_id: "1", course_id: "1" }

Meteor.publish('freeCourses', function () {
            this.added('freeCourses', Courses.find({}, {fields: {'Seasons.Episodes.paid_url': 0}}));
            this.ready();
        });
        Meteor.publish('premiumCourses', function () {
            //userPremiumCourses is array of course_ids
            var userPremiumCourses = userCourses.find({'user_id': this.userId}, {fields: {course_id: 1, _id: 0}}).map(
                function (doc) {
                    return doc.course_id;
                }
            );
            this.added('premiumCourses', Courses.find({_id: {$in: userPremiumCourses}}));
            this.ready();
        });
if(Meteor.isClient){
Meteor.subscribe('freeCourses');
Meteor.subscribe('premiumCourses');
}

我想在客户端获得两个不同的 collectionfreeCourses 和 premiumCourses。

我以前从未见过这样做,但如果可能的话,我相信您需要定义两个引用相同底层 mongo 集合的集合:

freeCourses = new Mongo.collection('userCourses');
premiumCourses = new Mongo.collection('userCourses');

我刚刚测试过,但失败了。

一个集合可以有多个出版物,每个出版物都有自己的查询参数和字段,但您似乎想要更像 SQL 视图 的内容。这在 Meteor afaik 中不存在。

所以我使用了 publishVirtual 函数。感谢@michel floyd

function publishVirtual(sub, name, cursor) {
  var observer = cursor.observeChanges({
    added  : function(id, fields) { sub.added(name, id, fields) },
    changed: function(id, fields) { sub.changed(name, id, fields) },
    removed: function(id)         { sub.remove(name, id) }
  })

  sub.onStop(function() {
    observer.stop() // important. Otherwise, it keeps running forever
  })
}

并将其添加到发布中:

Meteor.publish('freeCourses', function () {
    var cursor = Courses.find({}, {fields: {'Seasons.Episodes.paid_url': 0}});
    publishVirtual(this, 'freeCourses', cursor);
    this.ready();
});
Meteor.publish('premiumCourses', function () {
    //userPremiumCourses contains array of course_ids
    var userPremiumCourses = userCourses.find({'user_id': this.userId}, {fields: {course_id: 1, _id: 0}}).map(
        function (doc) {
            return doc.course_id;
        }
    );
    var cursor = Courses.find({_id: {$in: userPremiumCourses}});
    publishVirtual(this, 'premiumCourses', cursor);
    this.ready();
});

并为订阅制作了两个客户端集合:

if (Meteor.isClient) {
    freeCourses = new Mongo.Collection("freeCourses");
    premiumCourses= new Mongo.Collection("premiumCourses");

    Meteor.subscribe('freeCourses');
    Meteor.subscribe('premiumCourses');
}