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?
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ń.
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