我有一张包含两种类型(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);
我相信这会给我想要的结果,但我害怕的是:
- 组查询将返回我每个第一个 B 活动/用户/天的列表。我一次只展示 20 个活动,所以我只关心最近的 20 个 B 活动(最多,因为我展示了 20 个 A 和 B 组合)。这似乎真的很浪费。
- 在第一个查询中,我可以将传递给 $in 的数组修剪为 20 个 id。但是,因为用户可以查看下一页,所以我必须为第 2 页传入 40 个 id,为第 3 页传入 60 个等。到第 10 页,我的 $in 查询正在查找 200 条记录。不确定这是否是一个问题,但它让我担心。
有没有更好的方法来解决这个问题?希望很清楚,我知道这是一个令人困惑的情况。