gpt4 book ai didi

MongoDB、MapReduce 和排序

转载 作者:IT老高 更新时间:2023-10-28 13:14:45 24 4
gpt4 key购买 nike

我可能对此有点不知所措,因为我仍在学习 MongoDB 的来龙去脉,但这里继续。

现在我正在开发一种工具来搜索/过滤数据集,按任意数据点(例如流行度)对其进行排序,然后按 id 对其进行分组。我认为我能做到这一点的唯一方法是通过 Mongo 的 MapReduce 功能。

我不能使用 .group(),因为我正在使用超过 10,000 个键,而且我还需要能够对数据集进行排序。

我的 MapReduce 代码运行良好,除了一件事:排序。排序根本不想工作。

db.runCommand({
'mapreduce': 'products',
'map': function() {
emit({
product_id: this.product_id,
popularity: this.popularity
}, 1);
},
'reduce': function(key, values) {
var sum = 0;
values.forEach(function(v) {
sum += v;
});

return sum;
},
'query': {category_id: 20},
'out': {inline: 1},
'sort': {popularity: -1}
});

我已经在流行度数据点上有一个降序索引,所以它肯定因为缺少它而不起作用:

{ 
"v" : 1,
"key" : { "popularity" : -1 },
"ns" : "app.products",
"name" : "popularity_-1"
}

我只是不明白为什么它不想排序。

由于此功能的工作方式,我不能将结果集输出到另一个集合,然后对其运行 .find().sort({popularity: -1}) ,而不是内联结果集。

最佳答案

首先,Mongo map/reduce 不是为用作查询工具而设计的(就像在 CouchDB 中一样),它是为您运行后台任务而设计的。我在工作中使用它来分析流量数据。

但是,您做错的是您将 sort() 应用于您的输入,但这没有用,因为当 map() 阶段完成时,中间文档按每个。因为您的 key 是一个文档,所以它按 product_idpopularity 排序。

这就是我生成数据集的方式

function generate_dummy_data() {
for (i=2; i < 1000000; i++) {
db.foobar.save({
_id: i,
category_id: parseInt(Math.random() * 30),
popularity: parseInt(Math.random() * 50)
})
}
}

这是我的 map/reduce 任务:

var data = db.runCommand({
'mapreduce': 'foobar',
'map': function() {
emit({
sorting: this.popularity * -1,
product_id: this._id,
popularity: this.popularity,
}, 1);
},
'reduce': function(key, values) {
var sum = 0;
values.forEach(function(v) {
sum += v;
});

return sum;
},
'query': {category_id: 20},
'out': {inline: 1},
});

这是最终结果(很长在这里粘贴):

http://cesarodas.com/results.txt

这是可行的,因为现在我们正在按 sorting、product_id、流行度 进行排序。您可以随心所欲地进行排序,只要记住最终排序是按 key 进行的,无论您的输入是如何排序的。

无论如何,正如我之前所说,您应该避免使用 Map/Reduce 进行查询,它是为后台处理而设计的。如果我是你,我会设计我的数据,以便我可以通过简单的查询访问它,在这种情况下,总是需要权衡复杂的插入/更新来进行简单的查询(这就是我对 MongoDB 的看法)。

关于MongoDB、MapReduce 和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12015064/

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