如何使用一组ID查找集合中的最新文档

时间:2015-11-08 10:07:59

标签: javascript mongodb meteor mongodb-query

我有一个集合Feeds和一个集合FeedElementsFeedElements个文档通过Feeds字段引用feedId集合。此外,所有FeedElements个文档都有日期字段submitted

我只想发布最新的(由字段submittedFeedElements文档确定,该文档只对应一个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查询中使用sortFeedElements.find()结合使用,我只会获得所有Feed文档的最新文档。但是,我希望有一个严格的1-1关系。那么,一个Feed文档 - >带有适当参考的最新FeedElements文档。

2 个答案:

答案 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)

您可以通过汇总框架$sort$group& $first

db.FeedElements.aggregate(
[
  { $match: { feedId: {$in:[1,2,3]}} },
  { $sort: { submitted: -1} },
  {
    $group:
    {
      _id: "$feedId",
      firstFeedElement: {$first : "$$ROOT"} // Get first whole document or you can take fields you want
    }
     }
   ]
)