2009-10-19 31 views
17

Tak, jestem dżokejem SQL (sorta) wchodzącym w CouchDb Map/Reduce world. Myślałem, że zorientowali się, jak odpowiednik COUNT (*) Funkcja SQL agregatora dla zbiorów couchdb z następujących czynności:Co to jest odpowiednik CouchDB funkcji agregującej SQL COUNT (*)?

mapa

function(doc) { 
    emit(doc.name, doc); 
} 

Zmniejszyć:

function(keys, values, rereduce){ 
    return values.length; 
} 

Który myślałem pracował, wracając coś w stylu:

"super fun C" 2 
"super fun D" 2 
"super fun E" 2 
"super fun F" 18 

... ale nie do końca. Kiedy dodaję rekord, liczba ta zmienia się dziko. Czasami liczba faktycznie spada, co było bardzo zaskakujące. czy robię coś źle? Może nie w pełni rozumiem koncepcję ostatecznej konsekwencji?

Odpowiedz

22

Wygląda na to, że zmniejsza się wyniki redukcji. Oznacza to, że reduce jest wywoływany więcej niż raz dla każdego klucza, a następnie wywoływany ponownie z tymi wynikami. Można sobie z tym poradzić z reduce funkcji takich jak to:

function(keys, values, rereduce) { 
    if (rereduce) { 
    return sum(values); 
    } else { 
    return values.length; 
    } 
} 

Alternatywnie, można zmienić funkcję map tak, że wartości są zawsze Ilość dokumentów:

// map 
function(doc) { 
    emit(doc.name, 1); 
} 

// reduce 
function(keys, values, rereduce) { 
    return sum(values); 
} 
+0

Używanie javascript redukuje funkcje zamiast wbudowanych spowoduje bardzo złą wydajność. Zobacz odpowiedź Davida – wallacer

31

w twojej redukują prostu umieścić:

_count

można również uzyskać sumę za pomocą:

_sum

więc zasadniczo zmniejszyć: „_sum” lub zmniejszyć „_count” i upewnij się, że Twoja mapa emituje wartość jest liczbą całkowitą (wartość liczbowa)

Zobacz "Built in reduce functions".

+1

To jest lepsza odpowiedź. Przeczytaj link David zamieszczony tutaj o wbudowanych funkcjach. – Lander

+0

To jest właściwie poprawna odpowiedź! –

Powiązane problemy