gpt4 book ai didi

mongodb - 在 mongo 中,我如何使用 map reduce 按最近的顺序获取一组

转载 作者:可可西里 更新时间:2023-11-01 09:11:04 25 4
gpt4 key购买 nike

我看到的 map reduce 示例使用诸如计数之类的聚合函数,但是使用 map reduce 获取每个类别中前 3 项的最佳方法是什么。

我假设我也可以使用 group 函数,但很好奇,因为他们声明分片环境不能使用 group()。但是,我实际上也有兴趣查看 group() 示例。

最佳答案

为了简化起见,我假设您有以下形式的文档:

{category: <int>, score: <int>}

我创建了 1000 个文档,涵盖 100 个类别:

for (var i=0; i<1000; i++) {
db.foo.save({
category: parseInt(Math.random() * 100),
score: parseInt(Math.random() * 100)
});
}

我们的映射器非常简单,只需发出类别作为键,以及一个包含分数数组的对象作为值:

mapper = function () {
emit(this.category, {top:[this.score]});
}

MongoDB 的 reducer 不能返回一个数组,而且 reducer 的输出必须和我们emit 的值类型相同,所以我们必须把它包装在一个对象中。我们需要一个分数数组,因为这将使我们的 reducer 计算出前 3 个分数:

reducer = function (key, values) {
var scores = [];
values.forEach(
function (obj) {
obj.top.forEach(
function (score) {
scores[scores.length] = score;
});
});
scores.sort();
scores.reverse();
return {top:scores.slice(0, 3)};
}

最后,调用 map-reduce:

db.foo.mapReduce(mapper, reducer, "top_foos");

现在我们有一个包含每个类别一个文档的集合,以及该类别中来自 foo 的所有文档的前 3 个分数:

{ "_id" : 0, "value" : { "top" : [ 93, 89, 86 ] } }
{ "_id" : 1, "value" : { "top" : [ 82, 65, 6 ] } }

(如果您使用与我上面相同的 Math.random() 数据生成器,您的确切值可能会有所不同)

您现在可以使用它来查询 foo 以获得最高分的实际文档:

function find_top_scores(categories) {
var query = [];
db.top_foos.find({_id:{$in:categories}}).forEach(
function (topscores) {
query[query.length] = {
category:topscores._id,
score:{$in:topscores.value.top}
};
});
return db.foo.find({$or:query});

此代码不会处理平局,或者更确切地说,如果存在平局,则 find_top_scores 生成的最终游标中可能会返回超过 3 个文档。

使用 group 的解决方案有点类似,尽管 reducer 一次只需要考虑两个文档,而不是键的分数数组。

关于mongodb - 在 mongo 中,我如何使用 map reduce 按最近的顺序获取一组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7290307/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com