4级订阅嵌套在流星中

时间:2016-02-25 03:42:28

标签: meteor meteor-blaze

我正在使用meteor,这是我的架构,每个都是一个单独的集合:

课程有很多讲座

讲座有很多问题

问题有很多答案

我想要一页,我可以在这里展示给定课程的讲座,问题和答案。我可以显示课程的讲座没问题,但我有显示更多嵌套项目的问题。我理想的是喜欢:

讲座有课程

答案有讲座(但不是courseId)

问题有答案(但不是讲课或课程)

这是明智的还是我应该在所有子组件中嵌入courseIds和lectureIds?这是我的铁路由器,我试图扩展与嵌套讲座有关的相同想法,但我遇到了如何为订阅提供讲座的绊脚石:

get-cannibalized

这是课程页面的订阅,再次是我不知道如何参加课程的绊脚石:

Router.route('/courses/:_id', {
    name: 'CoursePage',
    waitOn: function(){
        return [
            Meteor.subscribe('singleCourse', this.params._id),
            Meteor.subscribe('lectures', this.params._id),
            Meteor.subscribe('questions', this.params._id)
        ];
    },
    data: function() {
        return Courses.findOne(this.params._id);
    }
});

有人可以推荐一个好的方法来为单个页面执行此4级嵌套吗?我认为我错过了一些明显的东西,但我找不到谷歌搜索的好例子。

谢谢!

2 个答案:

答案 0 :(得分:2)

Mongo可以支持使用聚合。 $lookup将允许您像SQL连接一样在集合之间连接和收集数据。

在流星中使用它需要使用外部mongo($ Mong是Mongo 3.2的新查找,meteor的Mongo仍为2.6.7)以及meteorhacks:aggregate包这样的包。还有其他一些解决这个问题的软件包,正如评论中所提到的,聚合就是我用过的东西;使用它,您可以根据mongo聚合文档调用Courses.aggregate(...)以生成所需的数据。

在我的使用中,我定义了一个将过滤器参数作为参数

的Meteor方法
'aggregateReport':function(filterPersonnel, filterCourse, filterQuarter){
return Personnel.aggregate([{$match: filterPersonnel}, {$unwind: "$courses"},
  {$lookup: {from: "courses", localField: "courses", foreignField: "_id", 
  as: "course_docs"}}, {$unwind: "$course_docs"}, {$match: filterCourse}, 
  {$match: filterQuarter}]);

人员有:国家,课程日期,姓氏,姓名,...,课程#,课程。 (省略号与查询无关)。以上查询每个过滤器的Personnel,将其假脱机到每个课程一个记录(这是程序中许多人的成绩单视图),然后将课程中的信息course_docs添加到返回的人员,并且然后按课程参数和日期参数过滤。 代码和依赖关系是流星1.2; 2016年2月

答案 1 :(得分:2)

您可以Publish Composite打包。请参阅以下示例代码并根据您的集合模式进行编辑,

Meteor.publishComposite('singleCourse', function (courseId) {
    return [{
        find: function() {
            return Courses.find({ id: courseId});
        }
    }, {
        find: function() {
            return Lectures.find({ courseId: courseId});
        },
        children: [{
            find: function(lecture) {
                return Questions.find({ lectureId: lecture.id });
            },
            children: [{
                find: function(question) {
                   return Answers.find({ questionId: question.id });
                }
            }]
        }}
    }]
});

然后在您的路由器中,您只需拨打一个订阅电话,

Router.route('/courses/:_id', {
    name: 'CoursePage',
    waitOn: function(){
        return [
            Meteor.subscribe('singleCourse', this.params._id)
        ];
    },
    data: function() {
        return Courses.findOne(this.params._id);
    }
});

这是迄今为止最好的软件包之一(如果不是最好的),可以反复发布来自不同集合的相关文档集。

在进行这类反应连接时存在一些已知问题,但对于较小的数据集,这没有任何问题。

希望它有所帮助。