Агрегировать набор уникальных значений из всех документов в CouchDB - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь создать представление в CouchDB, которое возвращает группы уникальных значений. Например, список всех уникальных брендов и категорий.

функция карты

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=true, group_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"]
}

Примечание: Приведенный выше результат является просто демонстрацией того, что я ожидаю, что представление вернется. Он не должен быть структурирован как таковой (даже не уверен, что это возможно).

1 Ответ

0 голосов
/ 01 октября 2019

Я собираюсь ответить на это сам.

Сначала мы хотим определить функцию карты, которая выдает имя группы в качестве ключа и значение, заключенное в массив (что упрощает rereduce).

функция карты

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

Мы определяем пользовательскую функцию уменьшения

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=true и group_level=1 даст следующий результат:

+------------+-----------------------------------+
|    key     |               value               |
+------------+-----------------------------------+
| brands     | ["Brand A", "Brand B"]            |
| categories | ["Category A", "Category B"]      |
| colors     | ["Red", "White", "Blue", "Green"] |
+------------+-----------------------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...