1

我有一张包含两种类型(A 和 B)的活动表。这些活动由用户生成。我要做的是抓取最近的 20 个活动,但是对于 B 活动,只包括用户为当天创建的第一个活动。因此,如果用户在一天内创建了 4 个 A 活动和 4 个 B 活动,它将显示所有 4 个 A 活动,但只显示创建的第一个 B 活动。如果他们第二天再次创建相同数量的活动,查询将显示所有 8 个 A 活动,但仅显示 2 个 B 活动。

我目前的方法是使用 group by 子句获取 B 活动列表,按日期和用户分组。我有那个查询工作:

db.runCommand({    
  group: {
    ns: 'activities',
    $keyf: function(doc) {
      var created = doc._id.getTimestamp();
      created.setHours(0, 0, 0, 0);

      return { created: created, user: doc.user.id }
    },
    $reduce: function( curr, result ) { 
      // We only need the first activity of the day, but we can't sort (can we?)
      var earliestSoFar = result.date || new Date();

      if (earliestSoFar > curr._id.getTimestamp()) {
        result.id = curr._id;
        result.date = curr._id.getTimestamp();
      }
    },
    cond: {
      "type" : "B"
    },
    initial: {}
  }
})

我在想我可以从该结果集合中获取 id 并运行表单的最终查询:

.find({ $or: [
  { type: 'A' },
  { _id: { $in: getListOfIdsFromGroupQuery() }}
]}).limit(20);

我相信这会给我想要的结果,但我害怕的是:

  1. 组查询将返回我每个第一个 B 活动/用户/天的列表。我一次只展示 20 个活动,所以我只关心最近的 20 个 B 活动(最多,因为我展示了 20 个 A 和 B 组合)。这似乎真的很浪费。
  2. 在第一个查询中,我可以将传递给 $in 的数组修剪为 20 个 id。但是,因为用户可以查看下一页,所以我必须为第 2 页传入 40 个 id,为第 3 页传入 60 个等。到第 10 页,我的 $in 查询正在查找 200 条记录。不确定这是否是一个问题,但它让我担心。

有没有更好的方法来解决这个问题?希望很清楚,我知道这是一个令人困惑的情况。

4

0 回答 0