尝试执行不同的 reduce 时出现错误 (Reducer: )

error (Reducer: ) when attempting to do distinct reduce

我在尝试执行从 here 获得的 DISTINCT reduce 时遇到错误。我已经在啤酒样品桶上重现了这个错误,所以这应该很容易重现。我没有在 mapreduce_errors.txt 文件中看到任何错误,也没有在其他文件中看到任何可以引导我到任何地方的错误。 (如果您希望我搜索或 post 其他文件的片段,请询问)。

运行 couchbase enterprise 4 beta,在 Windows 2008 R2 上(这也发生在 3.0.1 社区版上。)。

这是我的地图功能(使用啤酒样本桶,直接随 couchbase 提供)。

function(doc, meta) {
  switch(doc.type) {
  case "brewery":
    emit(meta.id);
    break;
  }
}

这是我的 reduce 函数:

function(keys, values, rereduce) {
  return keys.filter(function (e, i, arr) {
    return arr.lastIndexOf(e) === i;
  });
}

这是错误:

reason: error (Reducer: )

如果有帮助的话,还有一个查看页面的imgur:http://i.imgur.com/KyLutMc.png

虽然此 reduce 用作开发视图,但不适用于生产视图。数据集必须太大,因此您必须实施重新归约。此文档应该对 http://docs.couchbase.com/admin/admin/Views/views-writing.html#reduce-functions

有所帮助

问题出在您的自定义 reduce 函数中:当它作为 re-reduce 的一部分被调用时,您没有处理这种情况。

根据Couchbase documentation

The base format of the reduce() function is as follows:

function(key, values, rereduce) {
    ...
    return retval;
}

The reduce function is supplied three arguments:

key: The key is the unique key derived from the map() function and the group_level parameter.

values: The values argument is an array of all of the values that match a particular key. For example, if the same key is output three times, data will be an array of three items containing, with each item containing the value output by the emit() function.

rereduce: The rereduce indicates whether the function is being called as part of a re-reduce, that is, the reduce function being called again to further reduce the input data.

When rereduce is false:

  • The supplied key argument will be an array where the first argument is the key as emitted by the map function, and the id is the document ID that generated the key.

  • The values is an array of values where each element of the array matches the corresponding element within the array of keys.

When rereduce is true:

  • key will be null.

  • values will be an array of values as returned by a previous reduce() function. The function should return the reduced version of the information by calling the return() function. The format of the return value should match the format required for the specified key.

粗体格式是我的,突出显示的词非常重要:您应该考虑到,有时您会收到值为 nullkeys 参数。

根据文档,您应该在 reduce() 函数中处理 rereducetrue 的情况,并且您应该知道在这种情况下,keys将是 null。对于 reduce() 函数,您可以这样做:

function(keys, values, rereduce) {
  if (rereduce) {
    var result = [];
    for (var i = 0; i < values.length; i++) {
      var distinct = values[i];
      for (var j = 0; j < distinct.length; j++) {
        result.push(distinct[j]);
      }
    }
    return result.filter(function (e, i, arr) {
      return arr.lastIndexOf(e) === i;
    });
  }

  return keys.filter(function (e, i, arr) {
    return arr.lastIndexOf(e) === i;
  });
}

在这里,我首先处理重新减少阶段。为此,我将在 values 参数中接收到的数组展平,然后删除合并后可能出现的重复项。

然后是您的原始代码,returns keys 参数数组没有重复项。

为了测试这个 reduce() 函数是否有效,我使用了以下 map() 函数:

function(doc, meta) {
  switch(doc.type) {
  case "brewery":
    emit(meta.id, null);
    emit(meta.id, null);
    break;
  }
}

这会故意生成重复项,然后由 reduce() 函数删除。