Login
Newsletter
Werbung

Do, 8. Juli 2010, 15:58

CouchDB – Datenbank mal anders

Daten abfragen - Ansichten

Bei realen Anwendungen kommt es eher selten vor, dass man alle Datensätze auf einmal benötigt. Um Daten gezielt abfragen und selektieren zu können, gibt es in CouchDB Ansichten, die so genannten Views, welche weiter oben bereits beschrieben wurden.

Zum Anlegen einer Ansicht klickt man im Auswahlmenü rechts oben auf Temporary View. Auf der nun erscheinenden Seite sieht man eine zweigeteilte Tabelle, in welche die Ansicht eingegeben werden kann. Die linke Spalte enthält die Map-Funktion, welche immer vorhanden sein muss, die rechte Spalte die Reduce-Funktion, welche optional ist.

Die Map-Spalte ist bereits mit einer sehr einfachen Ansicht vorbelegt, die wie folgt aussieht und weiter oben bereits erläutert wurde:

function(doc) {
  emit(null, doc);
}

Ein Klick auf Run führt die Funktion aus. Als Ergebnis erhält man die Schlüssel-Werte-Paare aus allen in der Datenbank vorhandenen Dokumenten.

Man kann als Schlüssel auch einen beliebigen String verwenden, wie z.B. im folgenden Beispiel:

function(doc) {
  emit("komplettes Dokument", doc);
}

Oder man verwendet gezielt Felder für die Ansicht:

function(doc) {
  emit (doc._id,doc.beschreibung)
}

Hier wird als Schlüssel die Dokumenten-ID verwendet, als Wert der Inhalt des Felds beschreibung.

Innerhalb der Funktion darf jeder gültige JavaScript-Code verwendet werden, dieser darf auch komplexer oder länger sein. Etwas umfangreichere Abfragen werden in den folgenden Beispielen gezeigt.

Die bisherigen Ansichten haben für jedes Dokument in der Datenbank ein Ergebnis zurückgeliefert. Möchte man selektieren, so sind die entsprechenden Kriterien in der Funktion zu hinterlegen. Möchte man nur die Namen und die Lizenz der Open-Source-Programme abfragen, so kann über den Schlüssel lizenz gefiltert werden, denn dieser Schlüssel existiert eben nur für diese Programme:

function(doc) {
  if (doc.lizenz)
    emit(doc._id,doc.beschreibung);
}

Durch die if-Bedingung wird der folgende emit-Befehl nur ausgeführt, wenn eben die Bedingung erfüllt ist.

Möchte man wissen, welche Programme für MacOS existieren, muss man den Inhalt des Feldes os heranziehen, also den darin hinterlegten Array. Dazu iteriert man direkt über das Array im Schlüssel os:

function(doc) {
  for (x in doc.os)
  {
    if (doc.os[x] == "MacOS")
      emit("MacOS Programm:",doc._id);
  }
}

Bisher ist immer nur die Map-Funktion zum Einsatz gekommen. Wie oben bereits erwähnt, kennt CouchDB aber auch eine Reduce-Funktion. Reduce-Funktionen werden immer auf eine vorangegangene Map-Funktion angewendet und dienen zum Zusammenfassen von Ergebnissen. Etwas vereinfacht ausgedrückt bedeutet das, dass die Werte aus der Map-Funktion nochmals eine Funktion durchlaufen.

Möchte man z.B. – Bezug nehmend auf das vorherige Beispiel – wissen, wie viele MacOS-Programme in der Datenbank sind, so ist dies über die folgenden Funktionen zu ermitteln:

// Map:
function(doc) {
  for (x in doc.os)
  {
    if (doc.os[x] == "MacOS")
      emit("MacOS:", 1);
  }
}

// Reduce:
function(key,values,rereduce) {
  return sum(values)
}

Die Reduce-Funktion wird in der rechten Spalte der Tabelle in Futon eingegeben. Als Ergebnis sollte man hier "MacOS": 3 erhalten. Die Map-Funktion funktioniert so, dass für jedes Programm, welches für MacOS verfügbar ist, als Schlüssel MacOS und als Wert die Zahl 1 zurückgegeben wird. Die folgende Reduce-Funktion summiert die Werte für alle identischen Schlüssel auf, was dann hier der Anzahl der MacOS-Programme entspricht. Wichtig ist, dass der Schlüssel immer gleich ist, da nur dann der Befehl sum auf die Werte angewendet wird. Mit der Zeile

emit(doc._id, 1);

würden auch nach der Reduce-Funktion noch drei Zeilen als Ergebnis erscheinen, eben weil drei verschiedene Schlüssel vorhanden sind.

Die Reduce-Funktion kann natürlich auch mehr als nur einen Befehl enthalten. Im folgenden Beispiel wird der Durchschnittspreis der kostenpflichtigen Programme berechnet:

// Map:
function(doc) {
  if (doc.preis)
    emit("Durchschnittspreis", doc.preis);
}

// Reduce:
function(key,values,rereduce) {
  return sum(values)/values.length
}

Das Prinzip ist ähnlich wie bei der Zählung der MacOS-Programme: Zuerst wird über die Map-Funktion ein Schlüssel-Werte-Paar für jedes kostenpflichtige Programm zurückgegeben, wobei der Schlüssel der String »Durchschnittspreis« und der Wert der Preis des Programms ist. Die Reduce-Funktion summiert dann die Werte und teilt das Ergebnis anschließend durch die Anzahl der Werte.

Bisher wurden alle Ansichten als temporäre Ansichten ausgeführt. Möchte man eine Ansicht speichern, was für den Produktivbetrieb der empfohlene Weg ist, klickt man auf der Seite Temporary View auf Save As.... Im folgenden Dialog wird man aufgefordert, den Namen des Design Documents anzugeben, unter dem die Ansicht gespeichert werden soll, sowie den Namen der Ansicht. Innerhalb eines Design Documents kann man mehrere Ansichten speichern. Bei der Namensvergabe sollte man darauf achten, dass man keine Leerzeichen verwendet, weil dies später beim Aufruf der Ansicht über das HTTP-API zu Problemen führen kann.

Daten mit shows darstellen

Neben den bisher ausführlich beschriebenen und benutzen Views kennt CouchDB auch so genannte shows. Dabei hinterlegt man die Formatierung für die Ausgabe ebenfalls direkt im Design Document.

Dazu im Folgenden ein Beispiel: Der Name eines Programms soll hervorgehoben, die Beschreibung soll als normaler Text dargestellt werden. Die entsprechende Funktion sieht so aus:

{
   "programme": "function(doc,req)
   { return {body:\"<strong>Programm: \"+doc._id+\"</strong>
Beschreibung: \"+doc.beschreibung}
   }"
}

shows-Funktionen können nicht getestet werden, sondern müssen direkt in einem existierenden Design Document angelegt werden. Dazu öffnet man ein Design Document, legt darin einen Schlüssel »shows« an und speichert als Wert die oben gezeigt Funktion. Heißt die Datenbank »fm« und das Design Document »fm_bsp«, so kann man die shows-Funktion für z.B. den gedit-Eintrag wie folgt aufrufen: http://localhost:5984/fm/_design/fm_bsp/_show/programme/Gedit.

Im Schlüssel »show« können auch mehrere show-Dokumente hinterlegt werden, sofern diese alle einen eigenen Namen haben. In der Abfrage muss wirklich "show", als Singular, geschrieben werden, auch wenn der Schlüssel in der Datenbank "shows" heißt.

Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung