我试图想出一种方法来计算非主键的存储桶中唯一值的数量。 Couchbase 2.5提供了一个n1ql方法来执行此操作。如果我们使用他们的啤酒样品,您可以发出以下命令:
从啤酒样本中选择计数(不同的样式)
返回标量值68.
我使用的是couchbase 2.2.0,它在技术上没有n1ql。我希望尽可能利用map / reduce / rereduce功能。原因是我拥有数百万条记录,而adhoc查询可能需要数天才能运行。有这样的方法吗?
对于地图功能,我有以下内容:
function (doc, meta) {
if ( doc.type == "beer")
emit(doc.style, doc.style);
}
对于reduce我有以下内容:
function(key, values, rereduce) {
var u = {}, a = [];
var results = {};
if (rereduce) {
for (var i = 0; i < values.length; i ++ ) {
for ( var j = 0; j < values[i].length; j ++ ) {
if (u.hasOwnProperty(values[i][j])) {
continue;
}
a.push(values[i][j]);
u[values[i][j]] = 1;
}
}
return (a);
} else {
for(var i = 0; i < values.length; i++) {
if (u.hasOwnProperty(values[i])) {
continue;
}
a.push(values[i]);
u[values[i]] = 1;
}
return(a);
}
}
这将返回一个具有唯一值但不是标量计数的数组。我能以任何方式获得独特啤酒风格的标量数量吗?感谢。
答案 0 :(得分:1)
对此的解决方案相对简单(至少对于视图而言)。
首先,没有必要输出doc / beer样式 键和值,因此你的map函数会更好:
function (doc, meta) {
if (doc.type == "beer") {
emit(doc.style, null)
}
}
接下来,只需使用内置的_count
reduce函数。
默认情况下,这只会输出您计算的存储桶中所有文档的数量,但是通过调用map函数并将过滤器参数group
设置为{{ 1}}和true
设置为group level
(确切的方法会因客户端SDK而异)。这样做会返回一个类似如下的对象数组:
1
使用{"rows":[
{"key":null,"value":1111},
{"key":"American Rye Ale or Lager","value":11},
{"key":"American-Style Amber/Red Ale","value":219},
{"key":"American-Style Barley Wine Ale","value":32},
{"key":"American-Style Brown Ale","value":187},
{"key":"American-Style Cream Ale or Lager","value":12},
{"key":"American-Style Dark Lager","value":1},
{"key":"American-Style Imperial Stout","value":55},
{"key":"American-Style India Black Ale","value":1},
{"key":"American-Style India Pale Ale","value":230},
{"key":"American-Style Lager","value":370},
{"key":"American-Style Light Lager","value":39},
{"key":"American-Style Pale Ale","value":393},
{"key":"American-Style Stout","value":241},
{"key":"American-Style Strong Pale Ale","value":8}
…
…
]
}
过滤器参数可以缩小此数组(键是特定样式,在这种情况下(或者您希望计算的任何内容))或类似地,您可以从中选择这个客户端。
答案 1 :(得分:0)
如果不同组的数量不会太大,请尝试在reduce函数中传递一个关联数组。
在啤酒样品桶中:
/**
* Map function
*/
function (doc, meta) {
if (doc.type == "beer" && doc.style)
emit(doc.style, null);
}
/**
* Reduce function
*/
function (keys, values, rereduce) {
count_by_key = {};
if (rereduce) {
for (i in values) {
_count_by_key = values[i];
for (key in _count_by_key) {
count_by_key[key] = _count_by_key[key] + (count_by_key[key] || 0);
}
}
} else {
if (keys)
for (i in keys) {
key = keys[i];
count_by_key[key] = 1 + (count_by_key[key] || 0);
}
}
return count_by_key;
}
结果值中的键数是独特啤酒样式的标量数。它也适用于关键过滤器。