流星中的 4 层订阅嵌套
4 level subscription nesting in meteor
我正在使用流星,这是我的模式,每个都是一个单独的集合:
课程有很多讲
讲座有很多问题
问题有很多答案
我想要 1 个页面来显示给定课程的讲义、问题和答案。我可以毫无问题地显示课程的讲座,但我在显示更多嵌套项目时遇到问题。理想情况下,我希望拥有:
讲座有 courseId
答案有 lectureId(但没有 courseId)
问题有 answerId(但没有 lectureId 或 courseId)
我应该在所有子组件中嵌入 courseId 和 lectureId 吗?这是我的铁路由器,我试图扩展与带问题的嵌套讲座相同的想法,但我遇到了如何为订阅提供讲座 ID 的绊脚石:
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);
}
});
这是课程页面的订阅,再次成为我的绊脚石,因为我不知道如何输入 lectureId:
Template.CoursePage.helpers({
Lectures: function() {
return Lectures.find({courseId: this._id});
},
Questions: function(lectureId) {
return Questions.find({courseId: this._id, lectureId: lectureId});
}
});
任何人都可以推荐一种在单个页面上进行这种 4 级嵌套的好方法吗?我认为我遗漏了一些明显的东西,但我无法通过 google 搜索找到一个很好的例子。
谢谢!
Mongo可以支持使用聚合。 $lookup 将允许您像 SQL 联接一样在集合之间连接和收集数据。
在 meteor 中使用它需要使用外部 mongo($lookup 是 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,将其假脱机到每个课程的一条记录(这是程序中许多人的抄本视图类型),然后将 Courses 中的信息作为 course_docs
添加到返回的 Personnel,并且然后按课程参数和日期参数过滤。 代码和依赖项是 meteor 1.2; 2016 年 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);
}
});
这是目前最好的包之一(如果不是最好的话),可以反应性地发布来自不同集合的一组相关文档。
在执行此类反应式连接时存在一些已知问题,但对于较小的数据集,这没有任何问题。
希望对您有所帮助。
我正在使用流星,这是我的模式,每个都是一个单独的集合:
课程有很多讲
讲座有很多问题
问题有很多答案
我想要 1 个页面来显示给定课程的讲义、问题和答案。我可以毫无问题地显示课程的讲座,但我在显示更多嵌套项目时遇到问题。理想情况下,我希望拥有:
讲座有 courseId
答案有 lectureId(但没有 courseId)
问题有 answerId(但没有 lectureId 或 courseId)
我应该在所有子组件中嵌入 courseId 和 lectureId 吗?这是我的铁路由器,我试图扩展与带问题的嵌套讲座相同的想法,但我遇到了如何为订阅提供讲座 ID 的绊脚石:
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);
}
});
这是课程页面的订阅,再次成为我的绊脚石,因为我不知道如何输入 lectureId:
Template.CoursePage.helpers({
Lectures: function() {
return Lectures.find({courseId: this._id});
},
Questions: function(lectureId) {
return Questions.find({courseId: this._id, lectureId: lectureId});
}
});
任何人都可以推荐一种在单个页面上进行这种 4 级嵌套的好方法吗?我认为我遗漏了一些明显的东西,但我无法通过 google 搜索找到一个很好的例子。
谢谢!
Mongo可以支持使用聚合。 $lookup 将允许您像 SQL 联接一样在集合之间连接和收集数据。
在 meteor 中使用它需要使用外部 mongo($lookup 是 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,将其假脱机到每个课程的一条记录(这是程序中许多人的抄本视图类型),然后将 Courses 中的信息作为 course_docs
添加到返回的 Personnel,并且然后按课程参数和日期参数过滤。 代码和依赖项是 meteor 1.2; 2016 年 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);
}
});
这是目前最好的包之一(如果不是最好的话),可以反应性地发布来自不同集合的一组相关文档。
在执行此类反应式连接时存在一些已知问题,但对于较小的数据集,这没有任何问题。
希望对您有所帮助。