我有一个数据库在沙发上有55,000,000文档。 许多文档对某些属性具有重复值,我想只为属性计算唯一值。计数couchdb行只有唯一
我是新来的couchdb和看到列表功能,但这太慢了迭代超过55万行和超时。
如果我做的:
"map": "function(doc) { if (doc.property) { emit(doc.property, 1); } }" "reduce": "_count"
,然后组,我得到的财产,包括重复的总数。 我怎样才能把这个减少到唯一?
谢谢。
我有一个数据库在沙发上有55,000,000文档。 许多文档对某些属性具有重复值,我想只为属性计算唯一值。计数couchdb行只有唯一
我是新来的couchdb和看到列表功能,但这太慢了迭代超过55万行和超时。
如果我做的:
"map": "function(doc) { if (doc.property) { emit(doc.property, 1); } }" "reduce": "_count"
,然后组,我得到的财产,包括重复的总数。 我怎样才能把这个减少到唯一?
谢谢。
你的地图功能没问题 - 你不能在这里做得更好。让我们着重于减少。
function(keys, values) {
var result = {};
var counter = 0;
keys.forEach(function(key) {
if (!result[key]) {
result[key] = true; // or whatever
counter++;
}
});
return counter;
}
function(keys, values) {
var result = [];
keys.forEach(function(key) {
if (result.indexOf(key[0]) == -1) {
result.push(key[0]);
}
});
return result.length;
}
我希望没有人在使用公认的答案从这里的Mariusz因为它不工作,至少在CouchDB中
CouchDB的减少功能还需要执行rereduces。这是减少其他几个减少的产出。
典型解决方案 使您的地图功能输出一个唯一的关键,然后减少_count。完全是你在你的问题中提出的建议,除了group = true。 这将计算每个独特的事物有多少个实例。每一行代表一个独特的事物。您可以轻松地统计列表函数中的总行数。
或者 您可能不希望让唯一的密钥例如,你可能有时间序列数据,并希望在一定时间范围内查询的唯一值,那么你必须包括在关键的日期时间。 要处理这种情况是棘手的。
选项1: 天真的解决方案是不计的独特价值,但只是让独特的价值观有点像这样的一个大名单,再算上他们都在客户端,或在列表功能之后。
function (keys, values, rereduce) {
var unique = {};
var getUniqueValues = function(values) {
for (i = 0; i < values.length; i++) {
if (values[i] in unique) {
} else {
unique[values[i]] = null;
}
}
}
if (rereduce === true) {
for (j = 0; j < values.length; j++) {
getUniqueValues(values[j]);
};
return Object.keys(unique);
} else {
getUniqueValues(values);
return Object.keys(unique);
}
}
选项2: 另一种选择是不降低在所有,只是在一个列表功能计数的独特价值。正如你所说,当有很多值时,这可能会变得缓慢。
选项3: 为了避免当计数了大量独特的东西是棘手的使用过多的内存。 它可以通过将位图上的唯一值散列到位来完成。 然后计算最终位图中有多少个1。
这也让你使用减少功能,因为你可以结合位图来结合你的独特结果。然后,最后在客户端或列表函数中计算位图中的1。
我还没有在CouchDB中尝试这种呢,但理论是合理的:http://highscalability.com/blog/2012/4/5/big-data-counting-how-to-count-a-billion-distinct-objects-us.html
一个需要注意的是,如果该位是不是足够大,有可能是一个小错误。但是,当您计算的数量非常大时,通常可以接受一个小错误。
你让我走在正确的轨道上,谢谢。为了清晰起见,我发布了修改的代码 – 2014-11-10 10:33:02