2009-10-19 12 views
17

Ja, ich bin ein SQL Jockey (sorta) der in die CouchDb Map/Reduce Welt kommt. Ich dachte, ich herausgefunden hatte, wie das Äquivalent der COUNT (*) SQL-Aggregator-Funktion für CouchDB Datensätze mit dem folgenden:Was ist das CouchDB-Äquivalent der SQL COUNT (*) - Aggregatfunktion?

Karte:

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

Reduce:

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

Was ich dachte, gearbeitet, etwas zurücksenden wie:

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

... aber nicht wirklich. Wenn ich einen Datensatz hinzufüge, variiert diese Anzahl stark. Manchmal sinkt die Zahl tatsächlich , was sehr überraschend war. Mache ich etwas falsch? Vielleicht verstehe ich das Konzept der letztendlichen Konsistenz nicht vollständig?

Antwort

22

Es sieht so aus, als würden Ihre Reduzierungsergebnisse reduziert. Das heißt, reduce wird mehr als einmal für jede Taste aufgerufen und dann mit diesen Ergebnissen erneut aufgerufen. Sie können, dass wie dies mit einer reduce Funktion Griff:

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

Alternativ können Sie die map Funktion ändern, so dass die Werte immer eine Anzahl von Dokumenten sind:

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

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

Mit Javascript reduzieren Funktionen anstelle der eingebauten eine sehr schlechte Leistung. Siehe Davids Antwort – wallacer

31

In Ihrem gerade setzen reduce:

_count

Sie können auch eine Summe erhalten mit:

_sum

so dass im Grunde reduzieren: "_sum" oder reduzieren: "_count" und stellen Sie sicher, dass Ihre Karte den Wert emittiert eine gültige ganze Zahl (Zahlenwert)

"Built in reduce functions" See.

+1

Dies ist die bessere Antwort. Lesen Sie den Link, den David hier über die eingebauten Funktionen geschrieben hat. – Lander

+0

Das ist eigentlich die richtige Antwort! –