![](/img/trans.png)
[英]Creating a many-to-many relationship between 2 mongodb collections by ids
[英]Creating a many to many relationship in a complex manner between 3 collections
我有3个收藏集, meteor.user()
, Categories
和Posts
。
用户可以通过将类别的ID保存在meteor.user()
中的数组中来选择关注任何类别的帖子。
最终目的是使用户拥有一个“个人”流,其中仅显示他们正在关注的类别中的帖子。
Posts collection
每个Posts collection
都包含一个以其为特色的Categories数组。
并且每个类别中都有一个帖子数组,该数组中的每个帖子都有一个帖子ID
字段。
其中id: 67
是类别的ID,而posts.ID: 74
是类别中的帖子的id。
以下是帖子集合中帖子的ID,与类别集合中的匹配posts.ID
用户保存类别ID,因此它在meteor.user()中显示为类别数组
当我这样做时
Template.userTimeline.helpers({
category: function() {
var posts = Category.find({
id: {
$in: Meteor.user().category
}
});
return posts
console.log(posts);
}
});
我可以做这个
{{#each category}}
<ul class="article-timeline">
{{#each posts}} {{ID}} {{/each}}
</ul>
{{/each}}
但这使我可以访问类别集合中的posts.ID并显示它。
如何进一步匹配上面代码获得的posts.ID与Post中Post
的ID,以便可以从Posts
集合中访问Posts
。 我可以做这样的事情吗?
Template.userTimeline.helpers({
category: function() {
var postsInCategory = Category.find({
id: {
$in: Meteor.user().category
}
});
var postMatch = Post.find({
ID: {
$in: postsInCategory
}
});
return postMatch
console.log(postMatch);
}
});
因此,您给我的解决方案是从我的Categories
集合中包含的post对象中获取post.title
,如下所示。
Category collection
此post
数组不完整,它是原始Posts Collection
的副本
我需要做的是使用上图所示的post.ID
即类别集合中的帖子数组,以与原始Posts
集合中的Posts
id
建立多对多关系 ,因此, post.title
具有post.title
我还需要具有title.rendered
,如下所示。
帖子集合。
如果您发现该ID
(不是顶级的ID,这是该类别的ID), post.ID
类别集合中的后阵列中是相同的id
在后的Posts
集合。 这就是全部的症结所在,可以帮助我建立一种关系,这样,我需要在原始的Posts
集合中显示title.rendered
,而不是显示Categories
集合中的post数组中的title
或post.title
。
听起来好像您无法控制数据格式,所以您必须使用嵌套循环来处理您拥有的格式。 我认为以下应该工作。
Template.userTimeline.helpers({
categories: function() {
return Category.find({
id: {
$in: Meteor.user().category
}
});
}
});
请注意,我更改了您的助手的名称。
{{#each category in categories}}
{{category.description}}
{{#each post in category.posts}}
{{post.title}}
{{/each}}
{{/each}}
cf http://blazejs.org/guide/spacebars.html#Each-in
编辑:
理想情况下,您将能够使用https://atmospherejs.com/reywood/publish-composite之类的程序包进行服务器端连接
但由于您对此无能为力,因此可以进行客户端加入。 您可以在模板的onCreated()中执行此操作(注意:这未经测试!)
this.subscribe('posts', function() {
let cursor = Categories.find({id: {$in: Meteor.user().category}});
cursor.observe({
added: function(newDocument) {
let category = newDocument;
// for this category, get all the associated post ids
let postIds = _.map(category.posts, function(p)) {
return p.ID;
};
// get the posts. we can fetch these because we waited for the publish of the posts collection.
let actualPosts = Posts.find({id: {$in: postIds}}).fetch();
// attach the actual posts to the category
category.actualPosts = actualPosts;
},
changed: function(newDocument, oldDocument) {
// if wanting to track changes to the categories, similar to added block
}
});
});
然后只需对模板进行简单的更改,就可以获取这些实际的帖子:
{{#each category in categories}}
{{category.description}}
{{#each post in category.actualPosts}}
{{post.title}}
{{/each}}
{{/each}}
进行客户端联接比较棘手,因为撰写本文时,您缺少对用户跟踪类别的反应性,并且在现有类别中添加了帖子。 因此您可以将所有内容进一步放入自动运行中。 可以跟踪对Meteor.user()。category的更改,但不确定是否可以跟踪类别中的发布更改。 但这应该可以帮助您实现目标。
编辑2:
哦,是的,如果这样做的话,除非您在模板上调用stop(),否则该侦听器将在模板消失时保持活动状态。 所以...
Template.userTimeline.onDestroyed(function() {
let handle = this.observeHandle.get();
if (handle) {
handle.stop();
}
});
Template.userTimeline.onCreated(function() {
let self = this;
self.observeHandle = new ReactiveVar();
self.subscribe('posts', function() {
let cursor = Categories.find({id: {$in: Meteor.user().category}});
let handle = cursor.observe({
added: function(newDocument) {
let category = newDocument;
// for this category, get all the associated post ids
let postIds = _.map(category.posts, function(p)) {
return p.ID;
};
// get the posts
let actualPosts = Posts.find({id: {$in: postIds}}).fetch();
// attach the actual posts to the category
category.actualPosts = actualPosts;
},
changed: function(newDocument, oldDocument) {
// if wanting to track changes, similar to added block
}
});
self.observeHandle.set(handle);
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.