Używanie Map reduce w CouchDB do wyświetlania mniejszej liczby wierszy

Powiedzmy, że masz dwa typy dokumentów, Klienci i zamówienia . Dokument Klienta zawiera podstawowe informacje, takie jak nazwa, adres itp. i zamówienia zawierają wszystkie informacje o zamówieniu za każdym razem, gdy klient coś zamawia. Podczas przechowywania dokumentów, type = order lub type = customer.

Jeśli wykonam funkcję mapy na zbiorze 10 klientów i 30 zamówień, wyświetli 40 wierszy. Niektóre wiersze będą klientami, niektóre będą zamówieniami.

The pytanie brzmi, jak napisać redukcję, aby informacja o zamówieniu była "wypchana" wewnątrz wierszy, które mają informacje o kliencie? Tak więc zwróci 10 wierszy( 10 klientów), ale wszystkie odpowiednie zamówienia dla każdego klienta.

Zasadniczo nie chcę oddzielnych rekordów na wyjściu, chcę je połączyć (zamówienia w jeden wiersz klienta) i myślę, że redukcja jest droga?

Author: Spacedman, 2011-05-20

1 answers

Nazywa się to zestawianie widoku i jest to bardzo przydatna technika CouchDB.

Na szczęście, nie potrzebujesz nawet kroku reduce. Wystarczy użyć map, aby zebrać klientów i ich zamówienia razem.

Setup

Kluczem jest to, że potrzebujesz unikalnego identyfikatora dla każdego klienta i musi on być znany zarówno z dokumentów klienta, jak i z dokumentów zamówienia.

Przykładowy klient:

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

Przykładowa kolejność:

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

Korzystałem wygodnie z identyfikator klienta jako dokument _id ale ważne jest to, że oba dokumenty znają tożsamość klienta.

Wypłata

Celem jest zapytanie na mapie, gdzie jeśli podasz ?key="customer [email protected]", otrzymasz najpierw (1) Informacje o kliencie i (2) wszystkie złożone zamówienia.

Ta funkcja mapy zrobiłaby to:

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);
  }
}

Wszystkie wiersze będą sortowane przede wszystkim na kliencie, o którym jest dokument, a sortowanie "tiebreaker" to liczba całkowita 1 lub 2. To sprawia, że dokumenty klienta zawsze sortują powyżej odpowiednich dokumentów zamówienia.

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

P. S. jeśli zastosujesz się do tego wszystkiego: zamiast 1 i 2 lepszą wartością może być null dla Klienta, to znacznik czasu zamówienia dla zamówienia. Będą sortowane identycznie jak wcześniej, z wyjątkiem teraz masz chronologiczną listę zamówień.

 30
Author: JasonSmith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-20 00:55:12