我有一个收藏 Feeds
和一个集合FeedElements
. FeedElements
文档有引用Feeds
通过 feedId
收集 field 。此外,所有 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
带有适当引用的文档。
最佳答案
如果我理解正确,您希望每个提要都有 lastActivity
字段,其中包含此提要的最后提交的提要元素的时间戳。您希望此字段具有反应性,并且您不想发布所有提要元素。
在这种情况下,聚合不是解决方案,因为 Meteor 不允许 react 聚合。
您需要使用低级发布 API:http://docs.meteor.com/#/full/meteor_publish (参见示例部分)。
低级发布 API (this.added
/this.removed
/this.changed
/others) 让您可以完全控制什么您通过 Meteor.publish
方法发送给客户端的数据。
以下是解决问题的方法(我使用 ES2015 语法):
// client/client.js
Meteor.subscribe('userFeeds', { userId: 1 });
// lib/lib.js
Feeds = new Mongo.Collection('feeds');
FeedElements = new Mongo.Collection('FeedElements');
// 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();
}
});
});
我还准备了 github repo https://github.com/imkost/feeds .只需 git clone
和 meteor run
。
关于javascript - 如何使用一组 ID 仅查找集合中的最新文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33592814/