2010-12-22 5 views
3

ich eine CouchDB Datenbank mit Dokumenten der Form habe: {Name, Zeitstempel, Wert}CouchDB: Filter und Gruppe in einer einzigen Ansicht

Ich habe eine Ansicht, die eine Zusammenfassung von Namen mit der Summe der zusammengebauten zeigt Werte. Dies ist eine direkte Reduktionsfunktion.

Jetzt möchte ich die Ansicht filtern nur Dokumente berücksichtigen, wo der Zeitstempel in einem bestimmten Bereich aufgetreten ist.

AFAIK das bedeutet, ich muss den Zeitstempel in den ausgegebenen Schlüssel der Kartenfunktion, z. emit([doc.Timestamp, doc.Name], doc)

Aber sobald ich das mache, sieht die Reduce-Funktion nicht mehr die Zeilen gruppiert, um die Summe zu berechnen. Wenn ich den Namen zuerst anführe, kann ich nur auf Level 1 gruppieren, aber wie filtere ich auf Level 2?

Gibt es eine Möglichkeit, dies zu tun?

Antwort

1

Ich glaube nicht, dass dies mit nur einem HTTP-Abruf und/oder ohne zusätzliche Logik in Ihrem eigenen Code möglich ist.

Wenn Sie emit([time, name]) Sie wäre in der Lage startkey=[timeA]&endkey=[timeB]&group_level=2 abfragen Elemente zwischen timeA und timeB zu bekommen gruppiert, wo ihre Zeitstempel und Namen identisch waren. Sie könnten dies dann nachbearbeiten, um zu addieren, wenn die Namen übereinstimmten, aber die anfängliche Ergebnismenge könnte größer sein, als Sie behandeln möchten.

Eine Alternative wäre emit([name,time]). Dann könnten Sie zuerst mit group_level=1 abfragen, um eine Liste von Namen zu erhalten [wenn Ihre Anwendung nicht bereits weiß, was sie sein werden]. Dann würden Sie für jede von denen Sie startkey=[nameN]&endkey=[nameN,{}]&group_level=2 abfragen, um die Zusammenfassung für jeden Namen zu erhalten.

(Beachten Sie, dass ich die JSON-Start/Ende-Tasten in meinen Abfrageexemplaren nicht codiert habe, um sie lesbarer zu machen. Sie müssen jedoch das entsprechende JavaScript-Zeichen encodeURIComponent von Ihnen verwenden .)

+0

Ist das wahr? Ich kann es nicht zur Arbeit bringen. –

+0

Könnte sein. Ich habe in meinem Beispiel einen Fehler behoben (Sie müssen ein Array ausgeben), das Ihnen helfen könnte. Es scheint jedoch, dass meine Beschreibung, wie die Ausgabe gruppiert wird, auch irreführend sein könnte, ich werde versuchen, sie als nächstes zu überarbeiten. – natevw

-2

Sie können keine Ansicht in einer Ansicht anzeigen. Sie müssen eine andere Map-Reduce-Ansicht schreiben, die die Filterung enthält, und am Ende die Gruppierung vornehmen. Etwas wie:

map: 
function(doc) { 
    if (doc.timestamp > start and doc.timestamp < end) { 
    emit(doc.name, doc.value); 
    } 
} 

reduce: 
function(key, values, rereduce) { 
    return sum(values); 
} 

Ich nehme an, Sie diese Ansicht nicht speichern kann, und haben es als Ad-hoc in Ihrer Anwendung Abfrage zu setzen.

Verwandte Themen