Mongodb 如何在mongo reduce函数中计算两个字段的计数和唯一计数
我有一个链接跟踪表,其中包含(除其他字段外)track_redirect和track_userid。我想输出一个给定链接的总计数,以及按用户id重复计数的唯一计数。因此,我们可以区分是否有人单击了同一链接5次 我尝试在key和values部分发出this.track_userid,但无法掌握如何在reduce函数中正确访问它们 因此,如果我回到它实际工作的时间,我有下面非常简单的代码——就像“我的第一个mapreduce函数”示例中的代码一样 地图 减少Mongodb 如何在mongo reduce函数中计算两个字段的计数和唯一计数,mongodb,mapreduce,Mongodb,Mapreduce,我有一个链接跟踪表,其中包含(除其他字段外)track_redirect和track_userid。我想输出一个给定链接的总计数,以及按用户id重复计数的唯一计数。因此,我们可以区分是否有人单击了同一链接5次 我尝试在key和values部分发出this.track_userid,但无法掌握如何在reduce函数中正确访问它们 因此,如果我回到它实际工作的时间,我有下面非常简单的代码——就像“我的第一个mapreduce函数”示例中的代码一样 地图 减少 function(k, vals) {
function(k, vals) {
var sum = 0;
for (var i in vals) {
sum += vals[i];
}
return sum;
}
我想知道发出附加用户ID信息并在mapreduce中访问它的正确方法。还是我想的不对
如果不清楚,我不想计算一个用户ID的总点击量,但要计算每个url+用户ID的唯一点击量-不计算用户ID在每个链接上的任何重复点击量
有人能给我指一下正确的方向吗?谢谢 您实际上可以在emit调用的第二个参数上传递任意对象。这意味着您可以利用它并在其中存储用户ID。例如,映射函数可以如下所示:
var mapFunc = function() {
if (this.track_redirect) {
var tempDoc = {};
tempDoc[this.track_userid] = 1;
emit(this.track_redirect, {
users_clicked: tempDoc,
total_clicks: 1
});
}
};
var reduceFunc = function(key, values) {
var summary = {
users_clicked: {},
total_clicks: 0
};
values.forEach(function (doc) {
summary.total_clicks += doc.total_clicks;
// Merge the properties of 2 objects together
// (and these are actually the userids)
Object.extend(summary.users_clicked, doc.users_clicked);
});
return summary;
};
您的reduce函数可能如下所示:
var mapFunc = function() {
if (this.track_redirect) {
var tempDoc = {};
tempDoc[this.track_userid] = 1;
emit(this.track_redirect, {
users_clicked: tempDoc,
total_clicks: 1
});
}
};
var reduceFunc = function(key, values) {
var summary = {
users_clicked: {},
total_clicks: 0
};
values.forEach(function (doc) {
summary.total_clicks += doc.total_clicks;
// Merge the properties of 2 objects together
// (and these are actually the userids)
Object.extend(summary.users_clicked, doc.users_clicked);
});
return summary;
};
summary对象的users\u clicked属性基本上将每个用户的id存储为一个属性(因为您不能有重复的属性,所以可以保证它将存储唯一的用户)。还请注意,您必须注意,传递给reduce函数的某些值可能是先前reduce的结果,上面的示例代码考虑了这一点。您可以在文档中找到有关上述行为的更多信息
为了获得唯一计数,您可以传入在reduce阶段完成时调用的finalizer函数:
var finalFunc = function(key, value) {
// Counts the keys of an object. Taken from:
// http://stackoverflow.com/questions/18912/how-to-find-keys-of-a-hash
var countKeys = function(obj) {
var count = 0;
for(var i in obj) {
if (obj.hasOwnProperty(i))
{
count++;
}
}
return count;
};
return {
redirect: key,
total_clicks: value.total_clicks,
unique_clicks: countKeys(value.users_clicked)
};
};
最后,您可以像这样执行map reduce作业(修改out属性以满足您的需要):
谢谢你,任,这是完全正确的。对于这个例子来说,使用我现在的数据是很好的,因为我现在已经理解了!很好的第一个回答,伙计!如果有人偶然发现了这条线索,这可能会很有用:我已经写了任的答案,包括显示每个阶段之间的数据