在同一查询管道中同时执行查找和MapReduce是否有效?
假设我有两个集合:
- items:
{ _id, group_id, createdAt }
- purchases:
{ _id, item_id }
我想基于每个组的最近x项购买数量获取前n个物品组。
如果我可以在item文档中获得购买数量,那么我可以聚合和排序,但事实并非如此。
我可以这样获取每个组的最近x项:
let x = 3;
let map = function () {
emit(this.group_id, { items: [this] });
};
let reduce = function (key, values) {
return { items: getLastXItems(x, values.map(v => v.items[0])) };
};
let scope = { x };
db.items.mapReduce(map, reduce, { out: { inline: 1 }, scope }, function(err, res) {
if (err) {
...
} else {
// res is an array of { group_id, items } where items is the last x items of the group
}
});
但是我缺少购买数量,所以无法使用它来对组进行排序,并输出前n个组(顺便说一句,我甚至不确定我能否做到这一点)。
我正在一个Web服务器上使用它,并使用作用域变量根据用户上下文运行查询,因此我不想将结果输出到另一个集合并必须在内联中完成所有操作。
=== 编辑1 === 添加数据示例:
样本数据可能如下:
// items
{ _id: '1, group_id: 'a', createdAt: 0 }
{ _id: '2, group_id: 'a', createdAt: 2 }
{ _id: '3, group_id: 'a', createdAt: 4 }
{ _id: '4, group_id: 'b', createdAt: 1 }
{ _id: '5, group_id: 'b', createdAt: 3 }
{ _id: '6, group_id: 'b', createdAt: 5 }
{ _id: '7, group_id: 'b', createdAt: 7 }
{ _id: '8, group_id: 'c', createdAt: 5 }
{ _id: '9, group_id: 'd', createdAt: 5 }
// purchases
{ _id: '1', item_id: '1' }
{ _id: '2', item_id: '1' }
{ _id: '3', item_id: '3' }
{ _id: '4', item_id: '5' }
{ _id: '5', item_id: '5' }
{ _id: '6', item_id: '6' }
{ _id: '7', item_id: '7' }
{ _id: '8', item_id: '7' }
{ _id: '9', item_id: '7' }
{ _id: '10', item_id: '3' }
{ _id: '11', item_id: '9' }
当 n = 3
且 x = 2
时,样本结果如下:
[
group_id: 'a', numberOfPurchasesOnLastXItems: 4,
group_id: 'b', numberOfPurchasesOnLastXItems: 3,
group_id: 'c', numberOfPurchasesOnLastXItems: 1,
]
n = 3
和x = 2
是什么意思? - kevinadin
是返回结果的限制,而x
表示每个组只查看最近的x
项。 - Guig