Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

German translation #460

Merged
merged 4 commits into from

2 participants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 30, 2011
  1. @vistahr
Commits on Mar 31, 2011
  1. @vistahr

    Translated

    vistahr authored
Commits on Apr 14, 2011
  1. @vistahr

    ready for review

    vistahr authored
Commits on Jun 9, 2011
  1. @vistahr

    draft of german translation

    vistahr authored
This page is out of date. Refresh to see the latest.
Showing with 134 additions and 113 deletions.
  1. +62 −55 editions/1/de/validation.html
  2. +72 −58 editions/1/de/views.html
View
117 editions/1/de/validation.html
@@ -1,4 +1,4 @@
-<title>Validation Functions</title>
+<title>Validierungsfunktionen</title>
<meta charset="utf-8">
@@ -10,77 +10,82 @@
<script src="../../../script.js"></script>
-<h2 id="validation">Validation Functions</h2>
+<h2 id="validation">Validierungsfunktionen</h2>
-<p>In this chapter, we look closely at the individual components of Sofa’s validation function. Sofa has the basic set of validation features you’ll want in your apps, so understanding its validation function will give you a good foundation for others you may write in the future.
+<p>In diesem Kapitel schauen wir uns die Sofa Validierungsfunktionen genauer an. Sofa benutzt grundlegende Validierungsfunktionen, die man in einer Anwendung benötigt. Wenn man diese Funktionen versteht, dann hat man genug Grundwissen um eigene Funktionen in weitere Anwendungen zu schreiben.
-<p>CouchDB uses the <code>validate_doc_update</code> function to prevent invalid or unauthorized document updates from proceeding. We use it in the example application to ensure that blog posts can be authored only by logged-in users. CouchDB’s validation functions—like map and reduce functions—can’t have any side effects; they run in isolation of a request. They have the opportunity to block not only end-user document saves, but also replicated documents from other CouchDBs.
+<p>CouchDB benutzt die <code>validate_doc_update</code> Funktion um unautorisierten Zugriff sowie ungültige oder unerwünschte Datenupdates zu verhindern. In der Beispielanwendung benutzen wir die Funktion, um sicherzustellen, dass Blogeinträge nur von autorisierten Benutzern bearbeitet werden können. Bei den CouchDB Validierungsfunktionen - genau wie bei den map und reduce Funktionen - werden keine Nebenläufigen Operationen ausgeführt, da diese isoliert von der Anfrage abgearbeitet werden. Man kann nicht nur direkte Zugriffe, sondern auch entfernte Zugriffe von anderen CouchDBs verhindern.
-<h3 id="functions">Document Validation Functions</h3>
+<h3 id="functions">Dokument Validierungsfunktionen</h3>
-<p>To ensure that users may save only documents that provide these fields, we can validate their input by adding another member to the <code>_design/</code> document: the <code>validate_doc_update</code> function. This is the first time you’ve seen CouchDB’s external process in action. CouchDB sends functions and documents to a JavaScript interpreter. This mechanism is what allows us to write our document validation functions in JavaScript. The <code>validate_doc_update</code> function gets executed for each document you want to create or update. If the validation function raises an exception, the update is denied; when it doesn’t, the updates are accepted.
-
-<p>Document validation is optional. If you don’t create a validation function, no checking is done and documents with any content or structure can be written into your CouchDB database. If you have multiple design documents, each with a <code>validate_doc_update</code> function, all of those functions are called upon each incoming write request. Only if all of them pass does the write succeed. The order of the validation execution is not defined. Each validation function must act on its own. See <a href="#figure/1">Figure 1, “The JavaScript document validation function”</a>.
+<p>Um sicherzustellen, das Benutzer nur Dokumente speichern, dessen Felder auch gültig sind, benötigt man nur dem <code>_design</code> Dokument, die <code>validate_doc_update</code> Funktion hinzuzufügen. Das ist das erste mal, dass die CouchDB einen externen Prozess ausführt. Die CouchDB sendet Funktionen und Dokumente zu einem externen JavaScript Interpreter, was uns erlaubt, das wir die Validierungsfunktionen in CouchDB realisieren können. Die <code>validate_doc_update</code> Funktion wird für jedes Dokument das neu angelegt oder gespeichert wird, ausgeführt. Wenn die Validierung fehlschlägt und einen Fehler wirft, wird der Updatevorgang abgebrochen; wenn nicht, wird das Update ausgeführt.
+
+
+
+<p>Die Validierung des Dokumentes ist optional. Wenn keine Validierungsfunktionen existieren, dann wird keine Eingabe überprüft und alle Daten können in die Datenbank geschrieben werden. Wenn mehrere Design Dokumente mit einer <code>validate_doc_update</code> Funktion existieren, dann wird bei einer ankommenden Anfrage jede Validierungsfunktion von jedem Designdokument aufgerufen und auf die Anfrage angewandt. Nur, wenn kein Fehler in dem gesamten Validierungsprozess auftreten, werden die Daten in die Datenbank geschrieben. Die Reihenfolge, in welcher die Validierungsfunktionen aufgerufen werden ist nicht festgelegt, so, dass jede Funktionen für sich selbst arbeiten muss und keine Abhängigkeiten zu den anderen Funktionen nutzen kann. Siehe auch <a href="#figure/1">Figur 1, “Die JavaScript, Dokumentvalidierungsfunktion”</a>.
<div class="figure" id="figure/1">
<img src="validation/01.png">
-<p class="caption">Figure 1. The JavaScript document validation function
+<p class="caption">Figur 1, die JavaScript, Dokumentvalidierungsfunktion
</div>
-<p>Validation functions can cancel document updates by throwing errors. To throw an error in such a way that the user will be asked to authenticate, before retrying the request, use JavaScript code like:
+<p>Validierungsfunktionen können Updates abbrechen, indem sie Fehler werfen. Um einen Fehler zu werfen, welcher zeigt, das der Anwender nicht autorisiert ist, die Abfrage durchzuführen, sieht der JavaScript-Code so aus:
<pre>
throw({unauthorized : message});
</pre>
-<p>When you’re trying to prevent an authorized user from saving invalid data, use this:
+<p>Um zu verhindern, das ein autorisierter Anwender, ungültige Daten in einen Datensatz schreibt, kann dieser Fehler geworfen werden:
<pre>
throw({forbidden : message});
</pre>
-<p>This function throws <code>forbidden</code> errors when a post does not contain the necessary fields. In places it uses a <code>validate()</code> helper to clean up the JavaScript. We also use simple JavaScript conditionals to ensure that the <code>doc._id</code> is set to be the same as <code>doc.slug</code> for the sake of pretty URLs.
+<p>Diese Funktion wirft einen <code>forbidden</code> Fehler, wenn die ankommenden Daten nicht gültig sind. Zusätzlich werden auch <code>validate()</code> Helfer eingesetzt um die Daten zu validieren. Es werden auch einfache JavaScript Konditionen genutzt um sicherzustellen, dass <code>doc._id</code> den selben Inhalt wie <code>doc._slug</code> besitzt. Dies ist nützlich um schöne URLs zu formen.
-<p>If no exceptions are thrown, CouchDB expects the incoming document to be valid and will write it to the database. By using JavaScript to validate JSON documents, we can deal with any structure a document might have. Given that you can just make up document structure as you go, being able to validate what you come up with is pretty flexible and powerful. Validation can also be a valuable form of documentation.
-<h3 id="context">Validation’s Context</h3>
+<p>Wenn keine Fehler geworfen werden, dann sieht CouchDB die einkommenden Daten als gültig an und schreibt diese in die Datenbank. Indem wir JavaScript verwenden um JSON Dokumente zu validieren, können wir jede mögliche erlaubte JSON-Struktur nutzen. Dadurch kann jedes gültige Dokument einfach und schnell validiert werden. Validierung ist auch eine gute Form der Dokumentation.
-<p>Before we delve into the details of our validation function, let’s talk about the context in which they run and the effects they can have.
+<h3 id="context">Wie arbeitet die Validierung</h3>
-<p>Validation functions are stored in <em>design documents</em> under the <code>validate_doc_update</code> field. There is only one per design document, but there can be many design documents in a database. In order for a document to be saved, it must pass validations on all design documents in the database (the order in which multiple validations are executed is left undefined). In this chapter, we’ll assume you are working in a database with only one validation function.
+<p>Bevor wir weiter ins Detail gehen, beschäftigen wir uns zuerst mit der Funktion der Validierung.
+
+
+<p>Validierungsfunktionen werden in <code>design documents</code> in dem Feld <code>validate_doc_update</code> gespeichert. Es gibt nur eine Validierungsfunktion pro Designdokument, aber es gibt mehrere Designdokumente in einer Datenbank. Beim speichern eines Datensatzes wird dieser, durch alle Validierungsfunktionen, aller Designdokumenten durchlaufen. (Die Reihenfolge der Abarbeitung ist nicht definiert.) In diesem Kapitel gehen wir einfachhalber davon aus, das es nur eine einzige Validierungsfunktion gibt.
-<h3 id="writing">Writing One</h3>
+<h3 id="writing">Eine Validierungsfunktion schreiben</h3>
-<p>The function declaration is simple. It takes three arguments: the proposed document update, the current version of the document on disk, and an object corresponding to the user initiating the request.
+<p>Die Funktionsdeklaration ist denkbar einfach. Es werden 3 Argumente erwartet: das veränderte Dokument, die aktuelle Version des Dokuments, und das entsprechende Objekt des Benutzers, welcher die Anfrage ausgeführt hat.
<pre>
function(newDoc, oldDoc, userCtx) {}
</pre>
-<p>Above is the simplest possible validation function, which, when deployed, would allow all updates regardless of content or user roles. The converse, which never lets anyone do anything, looks like this:
-
+<p>Dies ist die einfachste Validierungsfunktion, welche beim verändern der Daten, egal um welche Daten oder welchen Benutzer es sich handelt, alles zulässt. Umgekehrterweise sieht die Funktion die alles blockiert, so aus:
+
<pre>
function(newDoc, oldDoc, userCtx) {
throw({forbidden : 'no way'});
}
</pre>
-<p>Note that if you install this function in your database, you won’t be able to perform any other document operations until you remove it from the design document or delete the design document. Admins can create and delete design documents despite the existence of this extreme validation function.
+<p>Beachte, dass durch diese Funktion in der Datenbank, solange keine Daten mehr verändert werden können, bis diese aus dem Designdokument entfernt wurde. Administratoren können trotz dieser Einschränkungen Designdokumente bearbeiten, so, dass diese Funktion auch wieder entfernt werden kann.
-<p>We can see from these examples that the return value of the function is ignored. Validation functions prevent document updates by raising errors. When the validation function passes without raising errors, the update is allowed to proceed.
+<p>Anhand dieser Beispiele können wir sehen, das die return-Anweisung ignoriert wird. Validierungsfunktionen verhindern Updates mithilfe von Exceptions.
+Wenn ein Update ohne Fehler alle Validierungsfunktionen durchläuft, dann wird dieses ausgeführt und fest in die Datenbank geschrieben.
-<h4 id="type">Type</h4>
+<h4 id="type">Typen</h4>
-<p>The most basic use of validation functions is to ensure that documents are properly formed to fit your application’s expectations. Without validation, you need to check for the existence of all fields on a document that your MapReduce or user-interface code needs to function. With validation, you know that any saved documents meet whatever criteria you require.
+<p>Das wichtigste einer Validierungsfunktion ist, sicherzustellen, dass Dokumente alle Felder enthalten die eine Anwendung benötigt. Ohne Validierung, müssten man die Vollständigkeit eines Dokumentes in den MapReduce Funktionen sicherstellen. Mit Validierung weiß man, dass alle benötigten Felder beim speichern vorhanden sind.
-<p>A common pattern in most languages, frameworks, and databases is using types to distinguish between subsets of your data. For instance, in Sofa we have a few document types, most prominently <code>post</code> and <code>comment</code>.
+<p>Ein übliches Muss in vielen Sprachen, Frameworks und Datenbanken ist, das Benutzen von unterschiedlichen Typen um zwischen Datensätzen zu unterscheiden. Als Beispiel haben wir in Sofa die Dokumenttypen <code>post</code> und <code>comment</code>.
-<p>CouchDB itself has no notion of types, but they are a convenient shorthand for use in your application code, including MapReduce views, display logic, and user interface code. The convention is to use a field called <code>type</code> to store document types, but many frameworks use other fields, as CouchDB itself doesn’t care which field you use. (For instance, the CouchRest Ruby client uses <code>couchrest-type</code>).
-
-<p>Here’s an example validation function that runs only on posts:
+<p>CouchDB selber ist typenlos, aber sie sind ein praktisches Hilfsmiitel in Anwenungen, den MapReduce Views und dem Interface. Die Konvention besagt, dass es ein Feld namens <code>type</code> innerhalb der einzelnen Dokumente geben sollte, wobei viele Frameworks andere Felder benutzen. Wie der Benutzer das Feld nennt ist ihm überlassen. (Zum Beispiel nennt der CouchRest Ruby Client das Feld <code>couchrest-type</code>)
+
+<p>Hier ist eine Beispiel Validierungsfunktion welche nur auf Posts angewandt wird:
<pre>
function(newDoc, oldDoc, userCtx) {
@@ -90,8 +95,8 @@ <h4 id="type">Type</h4>
}
</pre>
-<p>Since CouchDB stores only one validation function per design document, you’ll end up validating multiple types in one function, so the overall structure becomes something like:
-
+<p>Da CouchDB in jedem Designdokument nur eine Validierungsfunktion zulässt, kann man auch mehrere Typen innerhalb einer Validierung abarbeiten. Die Funktion könnte dann so aussehen:
+
<pre>
function(newDoc, oldDoc, userCtx) {
if (newDoc.type == "post") {
@@ -106,7 +111,7 @@ <h4 id="type">Type</h4>
}
</pre>
-<p>It bears repeating that <code>type</code> is a completely optional field. We present it here as a helpful technique for managing validations in CouchDB, but there are other ways to write validation functions. Here’s an example that uses <em>duck typing</em> instead of an explicit <code>type</code> attribute:
+<p>Es sei nochmals gesagt, dass <code>type</code> ein optionales Feld ist. Wir stellen es hier als eine nützliche Technik vor, um den Validierungsprozess zu vereinfachen. Es gibt auch andere Wege eine solche Funktion zu schreiben. Hier ist ein Beispiel das <em>duck typing</em>, anstatt von einem <code>type</code> Attribut benutzt:
<pre>
function(newDoc, oldDoc, userCtx) {
@@ -116,17 +121,17 @@ <h4 id="type">Type</h4>
}
</pre>
-<p>This validation function ignores the <code>type</code> attribute altogether and instead makes the somewhat simpler requirement that any document with both a title and a body must have an author. For some applications, typeless validations are simpler. For others, it can be a pain to keep track of which sets of fields are dependent on one another.
+<p>Dieser Weg der Validierung ignoriert das <code>type</code> Attribut völlig. Stattdessen wird hier davon ausgegangen, dass Dokumente, welche einen Titel und einen Body haben, auch einen Autor haben müssen. Für machen Anwendungen ist die typenlose Validation einfacher. Wiederrum kann es auch ein Nachteil sein, wenn andere Felder ihre Abhängigkeiten kennen.
-<p>In practice, many applications end up using a mix of typed and untyped validations. For instance, Sofa uses document types to track which fields are required on a given document, but it also uses duck typing to validate the structure of particular named fields. We don’t care what sort of document we’re validating. If the document has a <code>created_at</code> field, we ensure that the field is a properly formed timestamp. Similarly, when we validate the author of a document, we don’t care what type of document it is; we just ensure that the author matches the user who saved the document.
+<p>In der Praxis nutzen viele Anwendungen eine Mischung aus typenlosen und typisierten Validierungen. Sofa benutzt zum Beispiel Dokumenttypen, um nachzuvollziehen welche Felder eines Dokuments benötigt werden. Es wird aber auch Duck Typing genutzt, um die Struktur von speziellen Feldern zu validieren. Es ist egal welche Sorte von Dokumenten wir validieren. Wenn das Dokument eine <code>created_at</code> Feld hat, dann können wir sichergehen, dass das Feld einen passenden Timestamp beinhaltet. Das ist vergleichbar damit, dass wenn wir einen Autor von einem Dokument validieren, es uns egal ist, welchen Typ dieser hat. Wir wissen nur, dass der Autor dem Benutzer gleicht, welcher das Feld gespeichert hat.
-<h4 id="required">Required Fields</h4>
+<h4 id="required">Pflichtfelder</h4>
-<p>The most fundamental validation is ensuring that particular fields are available on a document. The proper use of required fields can make writing MapReduce views much simpler, as you don’t have to test for all the properties before using them—you know all documents will be well-formed.
+<p>Die wichtigste Form der Validierung ist, das wir sicherstellen, dass spezielle Felder in einem Dokument vorhanden sind.
-<p>Required fields also make display logic much simpler. Nothing says amateur like the word <code>undefined</code> showing up throughout your application. If you know for certain that all documents will have a field, you can avoid lengthy conditional statements to render the display differently depending on document structure.
+<p>Pflichtfelder machen die Anzeigenlogik viel einfacher. Nichts ist dilettantischer als wenn das Wort <code>undefined</code> zurückgegeben wird. Wenn ein Feld mit Sicherheit in einem Dokument immer vorkommt, dann kann man sich umständliche Abfrage aber auch sparen.
-<p>Sofa requires a different set of fields on posts and comments. Here’s a subset of the Sofa validation function:
+<p>Sofa benötigt verschiedene Felder bei Posts und Comments. Hier ist ein Ausschnitt einer Validierungsfunktion:
<pre>
function(newDoc, oldDoc, userCtx) {
@@ -149,15 +154,16 @@ <h4 id="required">Required Fields</h4>
}
</pre>
-<p>This is our first look at actual validation logic. You can see that the actual error throwing code has been wrapped in a helper function. Helpers like the <code>require</code> function just shown go a long way toward making your code clean and readable. The <code>require</code> function is simple. It takes a field name and an optional message, and it ensures that the field is not empty or blank.
+<p>Das ist unser erster Blick auf die Validierungslogik. Man kann sehen, dass der Codeabschnitt, welcher den Fehler wirft, in eine extra Funktion ausgelagert wurde. Helfer wie die <code>require</code> Funktion machen den Code einfach und leserlich. Die <code>require</code> Funktion ist dabei sehr einfach gehalten, sie erwartet ein Feld Name und eine optionale Message und stellt sicher, dass das Feld nicht leer ist.
-<p>Once we’ve declared our helper function, we can simply use it in a type-specific way. Posts require a <code>title</code>, a <code>timestamp</code>, a <code>body</code>, and an <code>author</code>. Comments require a <code>name</code>, a <code>timestamp</code>, and the <code>comment</code> itself. If we wanted to require that every single document contained a <code>created_at</code> field, we could move that declaration outside of any type conditional logic.
+<p>Wenn wir einmal die Helferfunktion deklariert haben, können wir diese immer wieder verwenden. Posts benötigt einen <code>title</code>, einen <code>timestamp</code>, einen <code>body</code>, und einen <code>author</code>. Comments benötigt einen <code>name</code>, einen <code>timestamp</code> und den <code>comment</code> selber. Wenn wir sicherstellen wollen, das jedes Dokument ein Feld <code>created_at</code> enthalten muss, dann können wir dies ausserhalb der Typendeklaration setzen.
+
<h4 id="timestamps">Timestamps</h4>
-<p>Timestamps are an interesting problem in validation functions. Because validation functions are run at replication time as well as during normal client access, we can’t require that timestamps be set close to the server’s system time. We can require two things: that timestamps do not change after they are initially set, and that they are well formed. What it means to be well formed depends on your application. We’ll look at Sofa’s particular requirements here, as well as digress a bit about other options for timestamp formats.
+<p>Timestamps sind ein interessantes Problem bei der Validierungsfunktion, da die Validierung nicht on-the-fly, sondern mit einer, wenn auch geringen, Zeitverzögerung ausgeführt wird. Wir können nicht erwarten, das der Timestamp mit dem Servertimestamp übereinstimmt. Wir können von 2 Dingen ausgehen: Timestamps verändern sich nicht, nachdem diese gesetzt wurden und sie sind haben ein richtiges Format. Was es heisst, das Timestamps im richtig Format gesetzt werden schauen wir uns anhand von Sofa an.
-<p>First, let’s look at a validation helper that does not allow fields, once set, to be changed on subsequent updates:
+<p>Als erstes gucken wir auf den Validationshelfer, welcher es nicht erlaubt, verhandene Felder zu verändern,
<pre>
function(newDoc, oldDoc, userCtx) {
@@ -169,30 +175,31 @@ <h4 id="timestamps">Timestamps</h4>
}
</pre>
-<p>The <code>unchanged</code> helper is a little more complex than the <code>require</code> helper, but not much. The first line of the function prevents it from running on initial updates. The <code>unchanged</code> helper doesn’t care at all what goes into a field the first time it is saved. However, if there exists an already-saved version of the document, the <code>unchanged</code> helper requires that whatever fields it is used on are the same between the new and the old version of the document.
-
-<p>JavaScript’s equality test is not well suited to working with deeply nested objects. We use CouchDB’s JavaScript runtime’s built-in <code>toJSON</code> function in our equality test, which is better than testing for raw equality. Here’s why:
+<p>Der <code>unchanged</code> Helfer ist ein bisschen komplexer als der <code>require</code> Helfer. Die erste Zeile in der Funktion verhindert das ausführen der Funktion bei Updates. Der <code>unchanged</code> Helfer kümmert sich nicht um den Inhalt des Feldes, welcher das erste mal gesetzt wird. Wenn also eine gespeicherte Version des Feldes schon existent ist, fordert der <code>unchanged</code> Helfer, das die neue, sowie die alte Version, gleich sind.
+<p>JavaScript’s Gleichheitsprüfung ist nicht geeignet um mit tieferen verschachtelten Objekten zu arbeiten. Wir nutzen die von der CouchDB integrierten <code>toJSON</code> JavaScript Funktion in unseren vergleichen, da diese besser geeignet ist, um die Objekte miteinander vergleichen zu können. Hier sieht man warum:
+
<pre>
js&gt; [] == []
false
</pre>
-<p>JavaScript considers these arrays to be different because it doesn’t look at the contents of the array when making the decision. Since they are distinct objects, JavaScript must consider them not equal. We use the <code>toJSON</code> function to convert objects to a string representation, which makes comparisons more likely to succeed in the case where two objects have the same contents. This is not guaranteed to work for deeply nested objects, as <code>toJSON</code> may serialize objects.
-
+<p>JavaScript sieht diese Arrays nicht als gleich an, da nicht der Inhalt bei der Überprüfung als Grundlage genommen wird, sondern diese als Objekte gesehen werden. Wir benutzen die <code>toJSON</code> Funktion um das Objekt zu einem String zu konvertieren, da die Stringvergleiche den Inhalt betrachten und wir dadurch die Gleichheit zweier Objekte mit demselben Inhalt feststellen können.
+
<div class="aside note">
-<p>The <code>js</code> command gets installed when you install CouchDB’s SpiderMonkey dependency. It is a command-line application that lets you parse, evaluate, and run JavaScript code. <code>js</code> lets you quickly test JavaScript code snippets like the one previously shown. You can also run a syntax check of your JavaScript code using <code>js file.js</code>. In case CouchDB’s error messages are not helpful, you can resort to testing your code standalone and get a useful error report.
+<p>Der <code>js</code> Befehl wird mitinstalliert, wenn auch CouchDB´s SpiderMonkey Abhängigkeit mitinstalliert wird. Dies ist eine Kommandozeilen Anwendung welche es erlaubt JavaScript Code on-the-fly zu parsen, evaluieren und auszuführen. Mit <code>js</code> kann man, wie oben gesehen, schnell JavaScript code testen. Man kann auch einen Syntaxcheck einer Datei mittels <code>js file.js</code> durchführen. Meistens sind die CouchDB Fehlerausgaben nicht sehr hilfreich, daher ist es öfter besser den Code eigenständig zu testen und eine aussagekräftige Fehlermeldung zu erhalten.
</div>
-<h4 id="authorship">Authorship</h4>
-
-<p>Authorship is an interesting question in distributed systems. In some environments, you can trust the server to ascribe authorship to a document. Currently, CouchDB has a simple built-in validation system that manages <em>node admins</em>. There are plans to add a database admin role, as well as other roles. The authentication system is pluggable, so you can integrate with existing services to authenticate users to CouchDB using an HTTP layer, using LDAP integration, or through other means.
+<h4 id="authorship">Rechteverwaltung</h4>
-<p>Sofa uses the built-in node admin account system and so is best suited for single or small groups of authors. Extending Sofa to store author credentials in CouchDB itself is an exercise left to the reader.
+<p>Die Rechteverwaltung ist innerhalb von verteilten Systemen eine interessante Frage. In manchen Umgebungen kann man dem Server vertrauen, wenn dieser die Autorschaft zu einem Dokument setzt. Zurzeit hat die CouchDB ein einfaches eingebautes System um die Rechte der <em>node admins</em> zu verwalten. Es gibt die Möglichkeit, innerhalb einer Datenbank, Administratorrechte zu vergeben, genau wie man andere Rechte vergeben kann. Die Authentifizierung der Benutzer zur CouchDB kann man über eine HTTP Schicht, welche LDAP nutzt, oder andere Wege realisieren.
+
-<p>Sofa’s validation logic says that documents saved with an author field must be saved by the author listed on that field:
+<p>Sofa nutzt den intigrierten vernetzten Administratorenaccount, da dieser am besten für einzelne oder größere Gruppen geeignet ist. Sofa so zu erweitern, das zusätzliche Autoreninformationen in der Datenbank gespeichert werden, soll die Aufgabe des Lersers sein.
+
+<p>Sofa’s Validierungslogik besagt, dass nur ein Autor, welcher in der Autorenliste gelistet ist, Dokumente speichern darf:
<pre>
function(newDoc, oldDoc, userCtx) {
@@ -203,8 +210,8 @@ <h4 id="authorship">Authorship</h4>
}
</pre>
-<h3 id="wrap">Wrapping Up</h3>
+<h3 id="wrap">Nachbereitung</h3>
-<p>Validation functions are a powerful tool to ensure that only documents you expect end up in your databases. You can test writes to your database by content, by structure, and by user who is making the document request. Together, these three angles let you build sophisticated validation routines that will stop anyone from tampering with your database.
+<p>Validierungsfunktionen sind ein starkes Mittel um sicherzustellen, dass nur die Dokumente die man erwartet auch in die Datenbank geschrieben werden. Es gibt 3 mögliche Formen auf welche wir bei der Validierung zurückgreifen können. Der Inhalt, die Struktur und derjenige, welcher die Anfrage ausgeführt hat. Zusammen sind diese 3 Validierungsmöglichkeiten ausreichend, um komplexe Routinen zu schreiben, die jeden davon abhalten die Daten der Datenbank zu manipulieren oder manipulierte Daten in die Datenbank zu schreiben.
-<p>Of course, validation functions are no substitute for a full security system, although they go a long way and work well with CouchDB’s other security mechanisms. Read more about CouchDB’s security in <a href="security.html">Chapter 22, Security</a>.
+<p>Mit Sicherheit sind die Validierungsfunktionen kein vollständiger Ersatz für Sicherheitssysteme, obwohl diese mit anderen Sicherheitsmechanismen sehr gut zusammenarbeiten. Mehr über CouchDB´s Sicherheit in <a href="security.html">Kapitel 22, Sicherheit</a>.
View
130 editions/1/de/views.html
@@ -106,11 +106,11 @@ <h3 id="what">Was ist eine View?</h3>
</div>
-<p>If you read carefully over the last few paragraphs, one part stands out: “When you query your view, CouchDB takes the source code and runs it for you on every document in the database.” If you have a lot of documents, that takes quite a bit of time and you might wonder if it is not horribly inefficient to do this. Yes, it would be, but CouchDB is designed to avoid any extra costs: it only runs through all documents once, when you <em>first</em> query your view. If a document is changed, the map function is only run once, to recompute the keys and values for that single document.
+<p>In den letzten Paragraphen haben wir folgenden Satz noch nicht beachtet : "Wenn man eine View aufruft, dann nimmt COuchDB den Source Code und führt diesen für jedes Dokument in der Datenbank aus." Wenn viele Dokumente in der Datenbank existieren, dann wird die Ausführung auf jedes Dokument sehr viel Zeit in Anspruch nehmen und man könnte meinen das die sehr ineffizient ist. Ist es auch, aber CouchDB ist so aufgebaut, das dieser Mehraufwand nicht so stark ins Gewicht fällt: es werden alle Dokumente nur einmalig durchlaufen, dann, wenn die View <em>das erste mal</em> aufgerufen wird. Wenn ein Dokument verändert wird, wir die Mapfunktion nur einmalig auf das Dokument angewandt um das Dokument mit den Keys und Values neu zu generieren.
-<p>The view result is stored in a B-tree, just like the structure that is responsible for holding your documents. View B-trees are stored in their own file, so that for high-performance CouchDB usage, you can keep views on their own disk. The B-tree provides very fast lookups of rows by key, as well as efficient streaming of rows in a key range. In our example, a single view can answer all questions that involve time: “Give me all the blog posts from last week” or “last month” or “this year.” Pretty neat. Read more about how CouchDB’s B-trees work in <a href="btree.html">Appendix F, The Power of B-trees</a>.
+<p>Das View Ergebnis wir in einem B-Baum gespeichert, genau wie die Struktur, welche für das Halten der Dokumente verantwortlich ist. View B-Bäume werden in separaten Dateien gespeichert so, dass für High-Performance Zugriffe die CouchDB diese auf ihrer eigenen Festplatte hat. Die B-Bäume stellen eine sehr schnelle Ausführung von Lookups von Rows mittels Keys sicher. Genauso schnell ist die Suche nach Bereichen von Keys. In unserem Beispiel kann eine einzelne View alle Anfragen beantworten: "Gibt mir alle Blogposts von letzter Woche" oder "vom letzten Monat" oder "von diesem Jahr". Lies mehr über die Arbeit von CouchDB mit B-Bäumen im <a href="btree.html">Anhang F, Die Macht der B-Bäume</a>.
-<p>When we query our view, we get back a list of all documents sorted by date. Each row also includes the post title so we can construct links to posts. Figure 1 is just a graphical representation of the view result. The actual result is JSON-encoded and contains a little more metadata:
+<p>Wenn wir unsere View aufrufen, bekommen wir eine Liste aller Dokumente, sortiert nach Datum, zurückgeliefert. Jede Zeile besitzt einen Posttitle so, dass wir Links zu Posts erstellen können. Figur 1 ist nur eine grafische Präsentierung des View Ergebnisses. Das eigentliche Ergebnis ist JSON-formatiert und beinhaltet ein bisschen mehr Metadaten.
<pre>
{
@@ -138,27 +138,31 @@ <h3 id="what">Was ist eine View?</h3>
}
</pre>
-<p>Now, the actual result is not as nicely formatted and doesn’t include any superfluous whitespace or newlines, but this is better for you (and us!) to read and understand. Where does that <code>"id"</code> member in the result rows come from? That wasn’t there before. That’s because we omitted it earlier to avoid confusion. CouchDB automatically includes the document ID of the document that created the entry in the view result. We’ll use this as well when constructing links to the blog post pages.
+<p>Das richtige Ergebnis ist nicht so schön formatiert und enthält auch keine überflüssigen Leerzeichen und Zeilen, aber so ist es besser für uns das Ergebnis zu lesen und zu verstehen. Wo kommt die <code>"id"</code> Zeile her, vorher war diese nicht da? Diese war auch vorher da, aber wir hatten sie für das bessere Verständnis weggelassen. CouchDB erzeugt die Zeile mit der ID automatisch. Wir werden diese bei unseren Links zu den Blogposts auch einsetzen.
-<h3 id="lookups">Efficient Lookups</h3>
+<h3 id="lookups">Effiziente Abfragen</h3>
-<p>Let’s move on to the second use case for views: “building efficient indexes to find documents by any value or structure that resides in them.” We already explained the efficient indexing, but we skipped a few details. This is a good time to finish this discussion as we are looking at map functions that are a little more complex.
-<p>First, back to the B-trees! We explained that the B-tree that backs the <code>key</code>-sorted view result is built only once, when you first query a view, and all subsequent queries will just read the B-tree instead of executing the map function for all documents again. What happens, though, when you change a document, add a new one, or delete one? Easy: CouchDB is smart enough to find the rows in the view result that were created by a specific document. It marks them <em>invalid</em> so that they no longer show up in view results. If the document was deleted, we’re good—the resulting B-tree reflects the state of the database. If a document got updated, the new document is run through the map function and the resulting new lines are inserted into the B-tree at the correct spots. New documents are handled in the same way. <a href="btree.html">Appendix F, The Power of B-trees</a> demonstrates that a B-tree is a very efficient data structure for our needs, and the crash-only design of CouchDB databases is carried over to the view indexes as well.
-<p>To add one more point to the efficiency discussion: usually multiple documents are updated between view queries. The mechanism explained in the previous paragraph gets applied to all changes in the database since the last time the view was queried in a batch operation, which makes things even faster and is generally a better use of your resources.
+<p>Das zweite Einsatzgebiet für views: “effiziente Indizies erstellen, um Dokumente mit beliebigem Wert oder Struktur zu finden.” Vorrangegangen wurden effiziente Indizies erklärt, aber es wurden ein paar Details übersprungen. Dies wird nun nachgehollt, bevor weiter auf map Funktionen eingegangen wird, da diese ein bisschen komplexer sind.
-<h4 id="one">Find One</h4>
+<p>Als erstes, zurück zu den B-Bäumen! Es wurde schon erläutert, dass der B-Baum, welcher den nach den <code>key</code>´s sortiert wurde, nur einmal, beim ersten ausführen, erstellt wird. Alle weiteren Abfragen nutzen diesen temporär erstellten B-Baum für weitere Abfragen, anstatt erneut die map Funktion erneut auf alle Werte anzuwenden. Was passiert, wenn neue Dokumente hinzugefügt, bestehende geändert oder welche gelöscht werden ? Ganz einfach: CouchDB ist intelligent genug die neuen Einträge in den Views zu filtern. Diese werden als <em>invalid</em> markiert und nicht mehr in der View ausgegeben. Wenn ein Dokumente gelöscht wird, so wird in dem Ergebnis das betroffene Dokument nicht mehr angezeigt. Wenn das Dokument geändert wird, dann durchläuft die neue Version des Dokuments erneut die map Funktion und wird in dem Ergebnis automatisch an der richtigen Stelle einsortiert. Neue Dokumente werden genau so verarbeitet. <a href="btree.html">Anhang F, Die Stärke der B-Bäume</a> demonstriert das ein B-Baum eine sehr effiziente Struktur für die CouchDB ist, and the crash-only design of CouchDB databases is carried over to the view indexes as well.
-<p>On to more complex map functions. We said “find documents by any value or structure that resides in them.” We already explained how to extract a value by which to sort a list of views (our <code>date</code> field). The same mechanism is used for fast lookups. The URI to query to get a view’s result is <code>/database/_design/designdocname/_view/viewname</code>. This gives you a list of all rows in the view. We have only three documents, so things are small, but with thousands of documents, this can get long. You can add <em>view parameters</em> to the URI to constrain the result set. Say we know the date of a blog post. To find a single document, we would use <code>/blog/_design/docs/_view/by_date?key="2009/01/30 18:04:11"</code> to get the “Biking” blog post. Remember that you can place whatever you like in the <code>key</code> parameter to the <code>emit()</code> function. Whatever you put in there, we can now use to look up exactly—and fast.
-<p>Note that in the case where multiple rows have the same key (perhaps we design a view where the key is the name of the post’s author), key queries can return more than one row.
+<p>Ein weiterer Punkt für Diskussion der Effizienz: in der Regel werden mehrere Dokumente zwischen den view Abfragen geändert. Der Mechanismus, des im vorigen erklärten Abschnittes, wird in einer Operation in der Datenbank ausgeführt so, dass die Resourcen besser genutzt werden und alles schneller abläuft.
-<h4 id="many">Find Many</h4>
+<h4 id="one">Einzelne Daten finden</h4>
-<p>We talked about “getting all posts for last month.” If it’s February now, this is as easy as <code>/blog/_design/docs/_view/by_date?startkey="2010/01/01 00:00:00"&amp;endkey="2010/02/00 00:00:00"</code>. The <code>startkey</code> and <code>endkey</code> parameters specify an inclusive range on which we can search.
+<p>Weiter zu komplexeren map Funktoonen. Wir sagten, "Dokumente mit beliebigem Wert und Struktur in der Datenbank zu finden." Wir haben schon erläutert, wie man einen Wert aus einer sortierten Liste finden kann (Mittels des <code>date</code> Feldes). Der selbe Mechanismus wir für schnelles finden von anderen Daten genutzt. Die URI um eine View abzufragen lauet <code>/database/_design/designdocname/_view/viewname</code>. Dies gibt eine Lust von allen Werten in einer View zurück. Wir haben hier nur drei Dokumente so, dass alles sehr klein ist, aber mit tausenden von Dokumenten, kann diese Abfrage lange dauern. Man kann <em>view parameters</em> zu der URI hinzufügen hinzufügen um ein anderes Ergebnis zu erhalten. Wenn wir das Datum des blog Posts kennen, dann können wir danach suchen. Um ein einzelnes Dokument zu erhalten, können wir <code>/blog/_design/docs/_view/by_date?key="2009/01/30 18:04:11"</code> benutzen. So erhalten wir den "Biking" Blog Post. Beachte das man jedes erdenkliche Feld als <code>key</code> Parameter zu der <code>emit()</code> Funktion aufnehmen kann. Welches Feld auch immer genommen wird, danach kann sehr schnell gesucht werden.
-<p>To make things a little nicer and to prepare for a future example, we are going to change the format of our date field. Instead of a string, we are going to use an array, where individual members are part of a timestamp in decreasing significance. This sounds fancy, but it is rather easy. Instead of:
+
+<p>Beachte das wenn mehrere Reihen die selben Felder haben (wenn eine view erstellt wird, wo ein Feld für den Namen des Post Autors genutzt wird), key Abfragen können mehr als eine Zeile zurückgeben.
+
+<h4 id="many">Mehrere Daten finden</h4>
+
+<p>Wir haben die Abfragen "alle Post des letzten Monats" bereits angesprochen. Wenn es jetzt Februar ist, dann würde die Abfrage so aussehen <code>/blog/_design/docs/_view/by_date?startkey="2010/01/01 00:00:00"&amp;endkey="2010/02/00 00:00:00"</code>. Der <code>startkey</code> und der <code>endkey</code> Parameter spezifizieren den Zeitraum in dem gesucht wird.
+
+<p>Um die Abfrage eleganter zu gestalten und für das weitere Kapitel nutzbarer zu machen, wird das Datumsfeld geändert. Anstatt einem String wird nun ein Array genutzt, bei dem die einzelnen Einträge Teil des Timestamps sind. Das klingt abwegig, ist aber ganz einfach. Anstatt von:
<pre>
{
@@ -166,13 +170,13 @@ <h4 id="many">Find Many</h4>
}
</pre>
-<p>we use:
+<p>nutzen wir nun:
<pre>
"date": [2009, 1, 31, 0, 0, 0]
</pre>
-<p>Our map function does not have to change for this, but our view result looks a little different. See <a href="#table/2">Table 2, “New view results”</a>.
+<p>Unsere map Funktion brauchen wir nicht zu verändern. Die Ausgabe der View sieht dafür ein wenig verändert aus. <a href="#table/2">Table 2, “Das neue View Ergebnis”</a>.
<div class="figure" id="table/2">
@@ -196,11 +200,11 @@ <h4 id="many">Find Many</h4>
</table>
-<p class="caption">Table 2. New view results
+<p class="caption">Table 2. Das neue View Ergebnis
</div>
-<p>And our queries change to <code>/blog/_design/docs/_view/by_date?key=[2009, 1, 1, 0, 0, 0]</code> and <code>/blog/_design/docs/_view/by_date?key=[2009, 01, 31, 0, 0, 0]</code>. For all you care, this is just a change in syntax, not meaning. But it shows you the power of views. Not only can you construct an index with scalar values like strings and integers, you can also use JSON structures as keys for your views. Say we tag our documents with a list of tags and want to see all tags, but we don’t care for documents that have not been tagged.
+<p>Die Abfragen lauten nun <code>/blog/_design/docs/_view/by_date?key=[2009, 1, 1, 0, 0, 0]</code> und <code>/blog/_design/docs/_view/by_date?key=[2009, 01, 31, 0, 0, 0]</code>. All die Abwandlung ist nur eine Syntaxänderung, die Abfragenlokig wird dabei nicht verändert, aber dies zeigt die Mächtigkeit der Views. Man kann nicht ausschließlich einen Index mit skalaren Werten wie Strings und Integers nutzen, auch JSON Strukturen können als keys für die Views genutzt werden. Angenommen unsere Dokumente werden mit mehreren Tags versehen, welche wir in unserem Ergebnis sehen möchten, uns aber diejenigen Einträge, welche nicht getagt wurden, nicht interessieren.
<pre>
{
@@ -228,25 +232,26 @@ <h4 id="many">Find Many</h4>
}
</pre>
-<p>This shows a few new things. You can have conditions on structure (<code>if(doc.tags.length &gt; 0)</code>) instead of just values. This is also an example of how a map function calls <code>emit()</code> multiple times per document. And finally, you can pass <code>null</code> instead of a value to the <code>value</code> parameter. The same is true for the <code>key</code> parameter. We’ll see in a bit how that is useful.
+<p>Dies zeigt ein paar neue Dinge. Man kann anstatt von Werten auch Konditionen in die Strukturen einbauen (<code>if(doc.tags.length &gt; 0)</code>). Dies ist auch ein Beispiel wie eine map Funktion, <code>emit()</code> mehrmals pro Dokument aufruft. Zudem kann auch <code>null</code> anstatt eines Wertes für den <code>value</code> Parameter genutzt werden. Dasselbe gilt für den <code>key</code> Parameter. Wir werden später sehen wie nützlich dieses Feature ist.
-<h4 id="reversed">Reversed Results</h4>
-<p>To retrieve view results in reverse order, use the <code>descending=true</code> query parameter. If you are using a <code>startkey</code> parameter, you will find that CouchDB returns different rows or no rows at all. What’s up with that?
+<h4 id="reversed">Umgekehrte Ergebnisse</h4>
-<p>It’s pretty easy to understand when you see how view query options work under the hood. A view is stored in a tree structure for fast lookups. Whenever you query a view, this is how CouchDB operates:
+<p>Um ein Ergebnis in umgekehrter Reihenfolge zu erhalten, kann man den <code>descending=true</code> Parameter nutzen. Wenn man gleichzeitig den <code>startkey</code> Parameter anhängt, gibt die CouchDB andere oder garkeine Spalten zurück.
+
+<p>Warum diesso ist, ist einfach zu verstehen wenn man weiß wie eine View Abfrage hinter den Kulissen arbeitet. Eine View ist einer Baum Struktur gespeichert, damit diese schnellausgeführt werden kann. Wenn man eine View abfragt, dann arbeitet CouchDB so:
<ol>
-<li>Starts reading at the top, or at the position that <code>startkey</code> specifies, if present.</li>
+<li>Es wird angefangen oben, oder an der Position welche <code>startkey</code> angibt, zu lesen.</li>
-<li>Returns one row at a time until the end or until it hits <code>endkey</code>, if present.</li>
+<li>Bis zur letzten, oder bis zur, mittels <code>endkey</code> angegebenen, Spalte</li>
</ol>
-<p>If you specify <code>descending=true</code>, the reading direction is reversed, <em>not</em> the sort order of the rows in the view. In addition, the same two-step procedure is followed.
+<p>Wenn <code>descending=true</code> genutzt wird, dann wird die Leserichtung verdreht, <em>not</em> aber die Sortierung der Spalten innerhalb der View. Nachfolgend wird das selbe Prinzip der zwei Schritte abgearbeitet.
-<p>Say you have a view result that looks like this:
+<p>Angenommen unser View Ergebnis sieht so aus:
<div>
@@ -272,7 +277,7 @@ <h4 id="reversed">Reversed Results</h4>
</div>
-<p>Here are potential query options: <code>?startkey=1&amp;descending=true</code>. What will CouchDB do? See #1 above: it jumps to <code>startkey</code>, which is the row with the key <code>1</code>, and starts reading backward until it hits the end of the view. So the particular result would be:
+<p>Eine potenzielle Abfragemöglichkeit sieht so aus: <code>?startkey=1&amp;descending=true</code>. Was wird die CouchDB tun ? Siehe oben bei Punkt 1: es wird beim <code>startkey</code> angefangen, welches die Spalte mit dem Key <code>1</code> ist und dann wird rückwärts bis ans Ende der View gelesen. Das Ergebnis sieht dann so aus:
<div>
@@ -296,7 +301,7 @@ <h4 id="reversed">Reversed Results</h4>
</div>
-<p>This is very likely not what you want. To get the rows with the indexes <code>1</code> and <code>2</code> in reverse order, you need to switch the <code>startkey</code> to <code>endkey</code>: <code>endkey=1&amp;descending=true</code>:
+<p>Das ist nicht das was wir möchten. Um die Spalten mit den Indizies <code>1</code> und <code>2</code> in umgekehrter Reihenfolge zu erhalten muss einfach der <code>startkey</code> zum <code>endkey</code> abgeändert werden : <code>endkey=1&amp;descending=true</code>:
<div>
@@ -320,13 +325,15 @@ <h4 id="reversed">Reversed Results</h4>
</div>
-<p>Now that looks a lot better. CouchDB started reading at the bottom of the view and went backward until it hit <code>endkey</code>.
+<p>Dann ist das gewünschte Ergebnis erreicht. CouchDB fängt am Ende der View an zu lesen und ließt bis zum Anfang oder bis der <code>endkey</code> erreicht wird.
+
+
+<h3 id="comments">Die View um Comments zum Post zu erhalten</h3>
-<h3 id="comments">The View to Get Comments for Posts</h3>
+<p>Wir benutzen hier ein Array um den <code>group_level</code> Abfragenparameter zu unterstützen. CouchDB´s Views werden in B-Baum Strukturen gespeichert (was später im Detail weiter erläutert wird). Aufgrund der Struktur der B-Bäume, können die Zwischenergebnisse des Reduce Vorgangs einfach in den Knoten zwischengespeichert werden so, dass die Reduceabfragen, egal in welchem Bereich, immer in einer Logarithmischen Zeit laufen. Siehe <a href="#figure/1">Figur 1, “Die Comments map Funktion”</a>.
-<p>We use an array key here to support the <code>group_level</code> reduce query parameter. CouchDB’s views are stored in the B-tree file structure (which will be described in more detail later on). Because of the way B-trees are structured, we can cache the intermediate reduce results in the non-leaf nodes of the tree, so reduce queries can be computed along arbitrary key ranges in logarithmic time. See <a href="#figure/1">Figure 1, “Comments map function”</a>.
-<p>In the blog app, we use <code>group_level</code> reduce queries to compute the count of comments both on a per-post and total basis, achieved by querying the same view index with different methods. With some array keys, and assuming each key has the value <code>1</code>:
+<p>In dem Blog nutzen wir <code>group_level</code> Reduceabfragen um die Anzahl der Comments für jeden Post, sowie die Anzahl aller Comments. Dies erreichen wir mit einer einzigen View über mehrere Methoden. Wir haben ein Array mit ein paar Keys, wobei wir annehmen, das jeder den Wert <code>1</code> hat:
<pre>
["a","b","c"]
@@ -336,7 +343,7 @@ <h3 id="comments">The View to Get Comments for Posts</h3>
["b","a","g"]
</pre>
-<p>the reduce view:
+<p>die Reduceview:
<pre>
function(keys, values, rereduce) {
@@ -344,7 +351,7 @@ <h3 id="comments">The View to Get Comments for Posts</h3>
}
</pre>
-<p>returns the total number of rows between the start and end key. So with <code>startkey=["a","b"]&amp;endkey=["b"]</code> (which includes the first three of the above keys) the result would equal <code>3</code>. The effect is to count rows. If you’d like to count rows without depending on the row value, you can switch on the <code>rereduce</code> parameter:
+<p>gibt die Anzahl der Spalten zwischen den start und endkey zurück. Mit <code>startkey=["a","b"]&amp;endkey=["b"]</code> (was die ersten drei, der oben stehenden keys beinhaltet) wäre das Ergebnis gleich <code>3</code>, womit wir die Spalten gezählt haben. Wenn die Anzahl der Spalten zurückgegeben werden soll, ohne, dass es einen Zusammenhang zu der jeweiligen Spalte gibt, kann man einfach den <code>rereduce</code> Paramter benutzen:
<pre>
function(keys, values, rereduce) {
@@ -360,20 +367,21 @@ <h3 id="comments">The View to Get Comments for Posts</h3>
<img src="views/01.png">
-<p class="caption">Figure 1. Comments map function
+<p class="caption">Figur 1. Die Comments map Funktion
</div>
-<p>This is the reduce view used by the example app to count comments, while utilizing the map to output the comments, which are more useful than just <code>1</code> over and over. It pays to spend some time playing around with map and reduce functions. Futon is OK for this, but it doesn’t give full access to all the query parameters. Writing your own test code for views in your language of choice is a great way to explore the nuances and capabilities of CouchDB’s incremental MapReduce system.
+<p>Das ist die Reduceview unserer Beispielanwendung um Comments zu zählen. Für die Ausgabe verwenden wir die Mapfunktion, was sinnvoller ist, anstatt Zeile für Zeile durchzugeben. Es kostet ein wenig Zeit mit den Map- und Reducefunktionen herumzuprobieren. Futon ist OK für diese Aufgaben, aber es erlaubt keinen vollen Zugriff auf alle Abfragenparameter. Eigene Abfragen in der präferierten Sprache zu schreiben, ist ein guter Weg den Hintergrund, sowie das MapReduce System von CouchDB zu verstehen.
-<p>Anyway, with a <code>group_level</code> query, you’re basically running a series of reduce range queries: one for each <em>group</em> that shows up at the <em>level</em> you query. Let’s reprint the key list from earlier, grouped at level <code>1</code>:
+
+<p>Mittels der <code>group_level</code> Abfrage, werden automatisch mehrere Reduceabfragen über einen bestimmten Bereich ausgeführt: einer für jede <em>group</em>, welcher das <em>level</em> ausgibt in dem man abfragt. Hier nochmal die Keyliste von vorher, mit dem Grouplevel <code>1</code>:
<pre>
["a"] 3
["b"] 2
</pre>
-<p>And at <code>group_level=2</code>:
+<p>Und mit <code>group_level=2</code>:
<pre>
["a","b"] 2
@@ -381,13 +389,13 @@ <h3 id="comments">The View to Get Comments for Posts</h3>
["b","a"] 2
</pre>
-<p>Using the parameter <code>group=true</code> makes it behave as though it were <code>group_level=Exact</code>, so in the case of our current example, it would give the number 1 for each key, as there are no exactly duplicated keys.
+<p>Das Benutzen des <code>group=true</code> Parameters gleicht dem <code>group_level=Exact</code> Parameters. In diesem Fall wird jedem Key die Nummer 1 gegeben, da keine doppelten Keys vorhanden sind.
<h3 id="reduce">Reduce/Rereduce</h3>
-<p>We briefly talked about the <code>rereduce</code> parameter to your reduce function. We’ll explain what’s up with it in this section. By now, you should have learned that your view result is stored in B-tree index structure for efficiency. The existence and use of the <code>rereduce</code> parameter is tightly coupled to how the B-tree index works.
+<p>Im vorigen Abschnitt wurde kurz der <code>rereduce</code> Parameter angesprochen. Was es mit diesem auf sich hat, wird hier weiter erläutert. Bislang wissen wir, das die Viewergebnisse der Effizienz wegeb in einem B-Baum gespeichert werden. Die Existenz und das Nutzen des <code>rereduce</code> Parameters ist eng mit dem Arbeitsvorgang der B-Bäume verbunden.
-<p>Consider the map result shown in <a href="#example/1">Example 1, “Example view result (mmm, food)”</a>.
+<p>Siehe das Mapergebnis in <a href="#example/1">Beispiel 1, “Beispiel Viewergebnis (mmm, food)”</a>.
<div id="example/1" class="figure">
@@ -406,11 +414,11 @@ <h3 id="reduce">Reduce/Rereduce</h3>
"vietnamese", 1
</pre>
-<p class="caption">Example 1. Example view result (mmm, food)
+<p class="caption">Beispiel 1. Beispiel Viewergebnis (mmm, food)
</div>
-<p>When we want to find out how many dishes there are per origin, we can reuse the simple reduce function shown earlier:
+<p>Wenn man herausfinden möchte, wieviel Gerichte pro Land vorhanden sind, kann man die Reducefunktion welche wir im vorigen Abschnutt genutzt haben, wieder benutzen:
<pre>
function(keys, values, rereduce) {
@@ -418,35 +426,41 @@ <h3 id="reduce">Reduce/Rereduce</h3>
}
</pre>
-<p><a href="#figure/2">Figure 2, “The B-tree index”</a> shows a simplified version of what the B-tree index looks like. We abbreviated the key strings.
+<p><a href="#figure/2">Figur 2, “Der B-Baum Index”</a> zeigt eine vereinfachte Version wie der Index eines B-Baum aussieht. Die Keystrings wurden hier gekürzt.
<div class="figure" id="figure/2">
<img src="views/02.png">
-<p class="caption">Figure 2. The B-tree index
+<p class="caption">Figur 2, Der B-Baum Index
</div>
-<p>The view result is what computer science grads call a “pre-order” walk through the tree. We look at each element in each node starting from the left. Whenever we see that there is a subnode to descend into, we descend and start reading the elements in that subnode. When we have walked through the entire tree, we’re done.
+<p>Das Viewergebnis ist, Informatikabsolventen nennen es einen Vordurchlauf durch die Baumstruktur. Gestartet von links, wird jedes Element und jeder Knoten betrachtet. Wenn ein Unterknoten existiert, dann wird dieser, genau wie der Hauptknoten, abgearbeitet. Wenn die gesamte Struktur durchlaufen wurde, ist der Vordurchlauf fertig.
+
+<p>CouchDB speichert sowohl die Schlüssel als auch die Werte in jedem Knoten. In unseren Fall ist es einfach, da es immer <code>1</code> ist, aber in anderen Fällen können alle Spalten auch unterschiedliche Werte haben. Wichtig ist, dass CouchDB alle Elemente, welche sich innerhalb eines Knoten in einer Reducefunktion befinden, (den <code>rereduce</code> Parameter auf <code>false</code> gesetzt) durchläuft und das Ergebnis in dem Elternknoten entlang der Ecke zu dem Unterknoten speichert. In diesem Fall ist der Wert jeder Ecke gleich <code>3</code>. Dieser repräsentiert das Reduceergebnis für jeden Knoten der auf diese Ecke zeigt.
+
-<p>You can see that CouchDB stores both keys and values inside each leaf node. In our case, it is simply always <code>1</code>, but you might have a value where you count other results and then all rows have a different value. What’s important is that CouchDB runs all elements that are within a node into the reduce function (setting the <code>rereduce</code> parameter to <code>false</code>) and stores the result inside the parent node along with the edge to the subnode. In our case, each edge has a <code>3</code> representing the reduce value for the node it points to.
+<p>In der Realität besitzen Knoten mehr als 1600 Elemente. CouchDb berechnet die Ergebnisse aller Elemente in mehreren Operationen, nicht alle auf einmal. (Was desaströs für den Speicherverbrauch wäre).
-<p>In reality, nodes have more than 1,600 elements in them. CouchDB computes the result for all the elements in multiple iterations over the elements in a single node, not all at once (which would be disastrous for memory consumption).
-<p>Now let’s see what happens when we run a query. We want to know how many <code>"chinese"</code> entries we have. The query option is simple: <code>?key="chinese"</code>. See <a href="#figure/3">Figure 3, “The B-tree index reduce result”</a>.
+<p>Wir wollen jetzt wissen, wie viele <code>"chinese"</code> Einträge wir haben. Die Abfrageoption ist einfach: <code>?key="chinese"</code>.
+Siehe <a href="#figure/3">Figur 3, “Das B-Baum Reduceergebnis”</a>.
+
<div class="figure" id="figure/3">
<img src="views/03.png">
-<p class="caption">Figure 3. The B-tree index reduce result
+<p class="caption">Figur 3. Das B-Baum Reduceergebnis
</div>
-<p>CouchDB detects that all values in the subnode include the <code>"chinese"</code> key. It concludes that it can take just the <code>3</code> value associated with that node to compute the final result. It then finds the node left to it and sees that it’s a node with keys outside the requested range (<code>key=</code> requests a range where the beginning and the end are the same value). It concludes that it has to use the <code>"chinese"</code> element’s value and the other node’s value and run them through the reduce function with the <code>rereduce</code> parameter set to <code>true</code>.
+<p>CouchDB erkennt das alle Werte in dem Unterknoten den <code>"chinese"</code> Key enthalten. Es werden genau <code>3</code> Werte gefunden, welche zur Berechnung des Endergebnisses genutzt werden. Danach wird der linke Knoten entdeckt, welcher auch den nötigen Schlüssel enthält, aber ausserhalb des angefragten Bereichs liegt (<code>key=</code> fragt einen Bereich, wo Anfang und Ende den selben Wert haben, an). Es werden die vorrangegangenen <code>"chinese"</code> Elemente, sowie die anderen Knotenelemente in der Reducefunktion genutzt. Wobei jetzt der <code>rereduce</code> Parameter auf <code>true</code> gesetzt wird.
+
+
+<p>Die Reducefunktion berechnet für das Abfrageergebnis <code>3 + 1</code> und liefert somit das gewünschte Resultat. <a href="#example/2">Beispiel 2, “Das Ergebnis ist 4”</a> zeigt mit Pseudocode den letzten Aufruf der Funktion.
-<p>The reduce function effectively calculates <code>3 + 1</code> on query time and returns the desired result. <a href="#example/2">Example 2, “The result is 4”</a> shows some pseudocode that shows the last invocation of the reduce function with actual values.
<div class="figure" id="example/2">
@@ -456,11 +470,11 @@ <h3 id="reduce">Reduce/Rereduce</h3>
}
</pre>
-<p class="caption">Example 2. The result is 4
+<p class="caption">Beispiel 2. Das Ergebnis ist 4
</div>
-<p>Now, we said your reduce function must actually reduce your values. If you see the B-tree, it should become obvious what happens when you don’t reduce your values. Consider the following map result and reduce function. This time we want to get a list of all the unique labels in our view:
+<p>Nun können wir sagen, das die Reducefunktion die Werte reduzieren muss. Wenn man sich einen B-Baum anschaut, sollte es offensichtlich werden, was passiert, wenn die Werte nicht reduziert werden. Weiter mit folgendem Mapergebnis und folgender Reducefunktion. Das Ergebnis soll eine Liste mit allen Labels sein, wobei jedes Label nur einmal vorkommen darf.
<pre>
"abc", "afrikan"
@@ -477,7 +491,7 @@ <h3 id="reduce">Reduce/Rereduce</h3>
"zul", "vietnamese"
</pre>
-<p>We don’t care for the key here and only list all the labels we have. Our reduce function removes duplicates; see <a href="#example/3">Example 3, “Don’t use this, it’s an example broken on purpose”</a>.
+<p>Der Key ist hier egal und es wird eine Liste genommen, die alle existierenden Labels beinhaltet. Die Reducefunktion entfernt dann die Duplikate; siehe <a href="#example/3">Beispiel 3, “Dies ist ein Beispiel was was produktiv nicht eingesetzt werden soll ”</a>.
<div class="figure" id="example/3">
@@ -494,11 +508,11 @@ <h3 id="reduce">Reduce/Rereduce</h3>
}
</pre>
-<p class="caption">Example 3. Don’t use this, it’s an example broken on purpose
+<p class="caption">Beispiel 3. Dies ist ein Beispiel was was produktiv nicht eingesetzt werden soll
</div>
-<p>This translates to <a href="#figure/4">Figure 4, “An overflowing reduce index”</a>.
+<p>Dies erklärt <a href="#figure/4">Figur 4, “Ein überlaufenden Reduceindex”</a>.
<p>We hope you get the picture. The way the B-tree storage works means that if you don’t actually reduce your data in the reduce function, you end up having CouchDB copy huge amounts of data around that grow linearly, if not faster with the number of rows in your view.
@@ -510,7 +524,7 @@ <h3 id="reduce">Reduce/Rereduce</h3>
<img src="views/04.png">
-<p class="caption">Figure 4. An overflowing reduce index
+<p class="caption">Figur 4. Ein überlaufenden Reduceindex
</div>
Something went wrong with that request. Please try again.