Ich wollte nur eine CouchDB-Antwort für alle, die neugierig sind, einfügen :)
Wie bereits in der ersten Antwort erwähnt, ist es nicht ratsam, das Autorendokument in das Artikeldokument einzubetten. Daher gehen die folgenden Beispiele von zwei Dokumenttypen aus: Artikel und Autoren.
CouchDB verwendet MapReduce Abfragen, die typischerweise in JavaScript geschrieben werden (aber auch Python, Ruby, Erlang und andere sind verfügbar). Die Ergebnisse einer MapReduce Abfrage werden bei der ersten Abfrage in einem Index gespeichert und dieser Index wird für alle zukünftigen Abfragen verwendet. Änderungen an der Datenbank werden bei weiteren Abfragen in den Index aufgenommen.
Das CouchDB API ist komplett HTTP-basiert, d.h. alle Anfragen an die Datenbank sind HTTP Verben (GET, POST, PUT, DELETE) unter verschiedenen URLs. Ich werde sowohl die MapReduce Abfragen (in JavaScript geschrieben) als auch die URL auflisten, die verwendet wird, um die entsprechenden Ergebnisse aus dem Index abzufragen.
1. Abrufen eines Artikels nach ID zusammen mit dem Autor
Die einfachste Methode hierfür sind zwei direkte Dokumentenabfragen:
GET /db/{article\_id}
GET /db/{author\_id}
...wobei {author_id} der Wert ist, der sich aus dem Feld author_id des Artikels ergibt.
2. Alle Artikel eines bestimmten Autors abrufen
MapReduce
function (doc) {
if (doc.type === 'article') {
emit(doc.author_id, doc);
}
}
GET /db/\_design/cms/\_view/articles\_by\_author?key="{author\_id}"
...wobei {author_id} die aktuelle ID des Autors ist.
3. Suche nach den ersten 10 Artikeln mit dem/den Autor(en), sortiert nach Erstellungsdatum
MapReduce
function (doc) {
function arrayDateFromTimeStamp(ts) {
var d = new Date(ts);
return [d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];
}
var newdoc = doc;
newdoc._id = doc.author_id;
newdoc.created_at = arrayDateFromTimeStamp(doc.created_at);
if (doc.type === 'article') {
emit(newdoc.created_at, newdoc);
}
}
Es ist möglich, Include-ähnliche "Joins" in CouchDB zu erstellen, indem man ?include_docs=true
in einer Ansichtsanfrage. Wenn Sie einen "_id"-Schlüssel in die Werteseite des emit (das zweite Argument) aufnehmen, dann wird das Hinzufügen von include_docs=true
zu Ihren Abfrageparametern hinzufügen, wird das Dokument, auf das die angegebene "_id" verweist, einbezogen. Im obigen Fall ersetzen wir die eigene "_id" des Dokuments (die wir nicht mehr benötigen) durch die "_id" des Autors, auf den verwiesen wird (den Wert von "author_id" im Artikeldokument). Die Abfrage der 10 wichtigsten Artikel mit den zugehörigen Autoreninformationen sieht wie folgt aus:
GET /db/\_design/cms/\_view/articles\_by\_date?descending=true&limit=10&include\_docs=true
Bei der Abfrage dieser URL wird eine Liste der letzten 10 Artikel in einem ähnlichen Format zurückgegeben:
{"rows":\[
{ "id":"article\_id",
"key":\[2011, 9, 3, 12, 5, 41\],
"value":{"\_id":"author\_id", "title":"..."},
"doc":{"\_id":"author\_id", "name":"Author Name"}
}
\]}
Mit demselben Index können Sie eine Liste aller Dokumente in beliebiger Granularität (Jahr, Monat, Tag, Stunde usw.) mit oder ohne Autorendaten erhalten.
Es gibt auch Methoden für die Verwendung von View Collation, um mehrere Dokumente aus einem einzigen Dokument zusammenzufassen (wie eine Seite in einem CMS, die auf unterschiedliche Inhalte verweist). In diesen Folien, die ich für die CouchConf im Juli erstellt habe, gibt es einige Informationen darüber, wie man das macht: http://www.slideshare.net/Couchbase/couchconfsfdesigningcouchbasedocuments
Wenn Sie weitere Fragen haben, lassen Sie es mich bitte wissen.