我有一个集合Feeds
和一个集合FeedElements
。 FeedElements
个文档通过Feeds
字段引用feedId
集合。此外,所有FeedElements
个文档都有日期字段submitted
。
我只想发布最新的(由字段submitted
)FeedElements
文档确定,该文档只对应一个Feeds
文档。
以下是我的尝试:
Meteor.publish('recentFeedElements', function (userId) {
var feedIds = Feeds.find({'userId': userId}).map(function(feed) {
return feed._id;
});
if (feedsIds.length > 0) return FeedElements.find({feedId: {$in: feedIds}}, {sort: {submitted: -1});
else this.ready();
});
问题是,如果我在limit
查询中使用sort
与FeedElements.find()
结合使用,我只会获得所有Feed
文档的最新文档。但是,我希望有一个严格的1-1关系。那么,一个Feed
文档 - >带有适当参考的最新FeedElements
文档。
答案 0 :(得分:4)
如果我理解正确,您希望每个Feed都有%include tempcode / source2;
字段,其中包含此Feed最后提交的Feed元素的时间戳。您希望此字段具有反应性,并且您不希望发布所有Feed元素。
在这种情况下,聚合不是解决方案,因为Meteor不允许反应性聚合。
您需要使用低级发布API:http://docs.meteor.com/#/full/meteor_publish(请参阅示例部分)。
低级别发布API(lastActivity
/ this.added
/ this.removed
/其他)可让您完全控制通过this.changed
方法发送给客户的数据。
以下是解决问题的方法(我使用ES2015语法):
Meteor.publish
// client/client.js
Meteor.subscribe('userFeeds', { userId: 1 });
// lib/lib.js
Feeds = new Mongo.Collection('feeds');
FeedElements = new Mongo.Collection('FeedElements');
我还准备了github repo https://github.com/imkost/feeds。只需// server/server.js
// When setting `submitted` field, automatically set `submittedAt` field
// (I use matb33:collection-hooks here)
FeedElements.before.update((userId, elem, fieldNames, modifier) => {
if (modifier.$set.submitted) {
modifier.$set.submittedAt = new Date();
}
});
function getLastActivity(feedId) {
const lastSubmittedElem = FeedElements.findOne(
{
feedId,
submitted: true,
},
{
sort: { submittedAt: -1 }
}
);
return lastSubmittedElem ? lastSubmittedElem.submittedAt : null;
}
Meteor.publish('userFeeds', function({ userId }) {
const elemsObservers = {};
// Observe all user feeds
var feedObserver = Feeds.find({ userId: userId }).observeChanges({
added: (feedId, fields) => {
// Observe feed elements of the feed
elemsObservers[feedId] = FeedElements.find({ feedId }).observeChanges({
changed: (elemId, fields) => {
// Update `lastActivity` field when new element is submitted
if (fields.submitted) {
this.changed('feeds', feedId, { lastActivity: fields.submittedAt });
}
},
});
fields.lastActivity = getLastActivity(feedId);
this.added('feeds', feedId, fields);
},
changed: (feedId, fields) => {
this.changed('feeds', feedId, fields);
},
removed: (feedId) => {
elemsObservers[feedId].stop();
delete elemsObservers[feedId];
this.removed('feeds', feedId);
},
});
this.ready();
this.onStop(function() {
feedObserver.stop();
for (const feedId in elemsObservers) {
elemsObservers[feedId].stop();
}
});
});
和git clone
。
答案 1 :(得分:0)