Ich benutze CouchDB. Ich möchte in der Lage sein, Vorkommen von Werten bestimmter Felder innerhalb eines Datumsbereichs zu zählen, der zum Abfragezeitpunkt angegeben werden kann. Ich scheine in der Lage zu sein, Teile davon zu tun, aber ich habe Probleme, den besten Weg zu verstehen, alles zusammen zu ziehen.
Annahme von Dokumenten mit einem Zeitstempelfeld und einem anderen Feld, z. B .:
%Vor% Ich kann problemlos eine Ansicht erstellen, in der Dokumente nach einem flexiblen Datumsbereich gefiltert werden . Dies kann mit einer Ansicht wie der folgenden erfolgen, die mit Schlüsselbereichsparametern, z.B. _view/all-docs?startkey=20120101-0000&endkey=20120201-0000
.
alle-Dokumente / map.js:
%Vor%Mit den obigen Daten würde dies eine CouchDB-Ansicht zurückgeben, die nur die ersten vier Dokumente enthält (die einzigen Dokumente im Datumsbereich).
Ich kann auch eine Abfrage erstellen, die Vorkommen eines bestimmten Feldes wie folgt aufzählt, die mit Gruppierung aufgerufen werden, d. h. _view/author-count?group=true
:
Autorenzählung / map.js:
%Vor%Autorenzählung / reduce.js:
%Vor%Dies würde etwas ergeben wie:
%Vor% Ich kann jedoch nicht den besten Weg finden, nach Datum und Anzahl zu filtern . Mit den obigen Daten wäre es beispielsweise möglich, Bereichsparameter wie startkey=20120101-0000&endkey=20120201-0000
anzugeben und ein Ergebnis wie dieses zu erhalten, bei dem das letzte Dokument aus der Zählung ausgeschlossen wird, da es außerhalb des angegebenen Datumsbereichs liegt:
Was ist der eleganteste Weg, dies zu tun? Ist das mit einer einzigen Abfrage möglich? Soll ich ein anderes CouchDB-Konstrukt verwenden oder reicht dafür eine Ansicht?
Sie können dem gewünschten Ergebnis mit einer Liste ziemlich nahe kommen:
%Vor%Dieser Entwurf kann als solcher angefordert werden:
%Vor%Dies ist langsamer als ein normales Map-Reduce und ist eine Art Workaround. Leider ist dies die einzige Möglichkeit, eine mehrdimensionale Abfrage durchzuführen, "Für welche CouchDB ist das nicht geeignet" .
Das Ergebnis der Anfrage dieses Designs wird etwa so aussehen:
%Vor%Was wir tun, ist im Grunde eine Menge von Elementen zu emittieren, dann verwenden Sie eine Liste, um sie zu gruppieren, wie wir wollen. Eine Liste kann verwendet werden, um ein Ergebnis beliebig darzustellen, ist aber oft auch langsamer. Während ein normales Map-Reduce zwischengespeichert werden kann und sich nur entsprechend den Diffs ändert, muss die Liste jedes Mal neu erstellt werden, wenn sie angefordert wird.
Es ist so langsam wie alle Elemente, die sich aus der Karte ergeben (der Aufwand für die Orchestrierung der Daten ist meist vernachlässigbar): viel langsamer als das Ergebnis einer Reduzierung.
Wenn Sie die Liste für eine andere Ansicht verwenden möchten, können Sie sie einfach in der von Ihnen angeforderten URL austauschen:
%Vor%Lesen Sie mehr über Listen auf dem CouchDB Wiki .
Obwohl Ihr Problem im Allgemeinen schwer zu lösen ist, kann es sehr hilfreich sein, einige Einschränkungen bei den möglichen Abfragen zu kennen. Z.B. Wenn Sie wissen, dass Sie nach Bereichen suchen, die ganze Tage / Monate abdecken, können Sie die Arrays von [year, month, day, time]
anstelle der Zeichenfolge verwenden:
Auch wenn Sie nicht vorhersagen können, dass alle möglichen Abfragen auf der Grundlage dieses Schlüsseltyps in die Gruppierung passen, kann die Aufteilung des Schlüssels Ihnen dabei helfen, Ihre Bereichsabfragen zu optimieren und die Anzahl der benötigten Suchen zu reduzieren (mit zusätzlichen Kosten) / p>