Использование карты уменьшить в CouchDB для вывода меньшего количества строк

Допустим, у вас есть два типа документов, клиенты и заказы. Документ клиента содержит основную информацию, такую ​​как имя, адрес и т.д., И заказы содержат всю информацию о заказе каждый раз, когда клиент заказывает что-то. При хранении документов тип = порядок или тип = клиент.

Если я выполняю функцию карты по набору из 10 клиентов и 30 заказов, она выведет 40 строк. Некоторые строки будут клиентами, некоторые будут заказывать.

Вопрос в том, как написать сокращение, чтобы информация о заказе была "заполнена" внутри строк с информацией о клиенте? Таким образом, он вернет 10 строк (10 клиентов), но все соответствующие заказы для каждого клиента.

В принципе, мне не нужны отдельные записи на выходе, я хочу объединить их (заказы в одну строку клиента), и я думаю, что сокращение - это способ?

Ответы

Ответ 1

Это называется сопоставление вида, и это очень полезный метод CouchDB.

К счастью, вам даже не нужен шаг reduce. Просто используйте map, чтобы клиенты и их заказы "сгустились" вместе.

Настройка

Ключ в том, что вам нужен уникальный идентификатор для каждого клиента, и он должен быть известен как из документов клиентов, так и из документов заказов.

Пример клиента:

{ "_id": "customer [email protected]"
, "type": "customer"
, "name": "Jason"
}

Пример порядка:

{ "_id": "abcdef123456"
, "type": "order"
, "for_customer": "customer [email protected]"
}

Я использовал идентификатор клиента как документ _id, но важно то, что оба документа знают идентификатор клиента.

Payoff

Цель - это запрос карты, где, если вы укажете ?key="customer [email protected]", вы получите сначала (1), информацию о клиенте и (2) все размещенные ордера.

Эта функция отображения сделает следующее:

function(doc) {
  var CUSTOMER_VAL = 1;
  var ORDER_VAL    = 2;
  var key;

  if(doc.type === "customer") {
    key = [doc._id, CUSTOMER_VAL];
    emit(key, doc);
  }

  if(doc.type === "order") {
    key = [doc.for_customer, ORDER_VAL];
    emit(key, doc);
  }
}

Все строки будут сортироваться в первую очередь на клиенте, о котором идет речь, а сортировка "тай-брейкер" - это целое число 1 или 2. Это делает документы клиентов всегда сортированными над соответствующими документами заказов.

["customer [email protected]", 1], ...customer doc...
["customer [email protected]", 2], ...customer order...
["customer [email protected]", 2], ...customer other order.
... etc...
["customer [email protected]", 1], ... different customer...
["customer [email protected]", 2], ... different customer order

P.S. Если вы будете придерживаться всего этого: вместо 1 и 2 для клиента может быть null лучшее значение, а затем отметка времени заказа для заказа. Они будут сортироваться одинаково, как и раньше, но теперь у вас есть хронологический список заказов.