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

标签 javascript mongodb meteor mongodb-query

我有一个收藏 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 clonemeteor run

关于javascript - 如何使用一组 ID 仅查找集合中的最新文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33592814/

相关文章:

Mongodb:按数组对象排序文档

javascript - 在数组中使用字符串

javascript - 如何复制对象数组的数组并能够操作复制的数组而不影响原始数组

php - 如何在mongodb查询生成器中 "group by"字段 "count"?

javascript - 在jade模板中显示mongodb集合

meteor - 我应该在哪里正确地把我的常量放在 meteor 中

Meteor.js - 使用提示让 Mongo 使用索引?

javascript - 如何有条件地将模板和 javascript 文件发送到 meteor 中的客户端?

javascript - 在 UIWebView 中从 JavaScript 获取返回值

javascript - 如何通过 Node.js 从 xml 中检索 URL?