从 CouchDB 中的所有文档中聚合一组唯一值

Aggregate a set of unique values from all documents in CouchDB

我正在尝试在 CouchDB 中创建一个包含 returns 组唯一值的视图。例如,所有独特品牌和类别的列表。

地图函数

function (doc) {
  emit("brands", [doc.brand]);
  emit("categories", [doc.category]);
}

归约函数

function (keys, values, rereduce) {
  return values.reduce(function(acc, value) {
    if (acc.indexOf(value[0]) === -1) {
      return acc.concat(value);
    }

    return acc;
  });
}

然后我用 group=truegroup_level=2 调用该视图。分组是正确的,但值不是唯一的。 value 是一个包含重复项的数组。

我想要实现的基本上是让 key 成为组名,例如 brands,而值是聚合的唯一值,例如 ["Brand A", "Brand B"] .

给出以下文件

[
  {
    "_id": "1",
    "brand": "Brand A",
    "category": "Category A",
    "colors": [
      "Red",
      "White"
    ]
  },
    {
    "_id": "2",
    "brand": "Brand B",
    "category": "Category B",
    "colors": [
      "Blue",
      "White"
    ]
  },
    {
    "_id": "3",
    "brand": "Brand A",
    "category": "Category B",
    "colors": [
      "Green",
      "Red"
    ]
  }
]

当我查询然后在 CouchDB 中查看时,我想得到以下结果

{
  "brands": ["Brand A", "Brand B"],
  "categories": ["Category A", "Category B"],
  "colors": ["Red", "White", "Blue", "Green"]
}

注意:上面的结果只是演示了我期望的视图return。它不必如此构造(甚至不确定是否可能)。

我自己来回答这个问题。

首先,我们要定义一个 map 函数,它将组名作为键和包装在数组中的值发出(使 rereduce 更容易)。

映射函数

function (doc) {
  emit("brands", [doc.brand]);
  emit("categories", [doc.category]);
  doc.colors.forEach(function(color) {
    emit("colors", [color]);
  })
}

我们定义了一个自定义的reduce函数

function (keys, values, rereduce) {
  return values.reduce(function(acc, value) {
    value.forEach(function(v) {
      if (acc.indexOf(v) === -1) {
        return acc.push(v);
      }
    });

    return acc;
  });
}

现在,使用 group=truegroup_level=1 调用视图将产生以下结果:

    
+------------+-----------------------------------+
|    key     |               value               |
+------------+-----------------------------------+
| brands     | ["Brand A", "Brand B"]            |
| categories | ["Category A", "Category B"]      |
| colors     | ["Red", "White", "Blue", "Green"] |
+------------+-----------------------------------+