2009-07-24 4 views
5

Ich verwende, was für die Erstellung einer Join-View einen gemeinsamen Trick scheint zu sein: Ich weißWas ist der maximale Wert für einen zusammengesetzten CouchDB-Schlüssel?

// a Customer has many Orders; show them together in one view: 
function(doc) { 
    if (doc.Type == "customer") { 
    emit([doc._id, 0], doc); 
    } else if (doc.Type == "order") { 
    emit([doc.customer_id, 1], doc); 
    } 
} 

kann ich einen einzelnen customer und alle damit verbundenen Order s die folgende Abfrage verwenden zu erhalten:

?startkey=["some_customer_id"]&endkey=["some_customer_id", 2] 

Aber jetzt habe ich meine Abfrage sehr eng an meinen Sichtcode gebunden. Gibt es einen Wert, den ich setzen kann, wo ich meine "2" setzen, um deutlicher zu sagen: "Ich möchte alles gebunden an diesen Kunden"? Ich glaube, ich habe

gesehen
?startkey=["some_customer_id"]&endkey=["some_customer_id", {}] 

Aber ich bin nicht sicher, dass {} ist bestimmtenach alles andere zu sortieren.

Guthaben auf cmlenz für die Join-Methode.

Eine weitere Klärung der CouchDB wiki page on collation:

Die Abfrage startkey=["foo"]&endkey=["foo",{}] wird mit "foo" in dem ersten Element, wie ["foo","bar"] und ["foo",["bar","baz"]] meisten Array-Schlüssel entsprechen. Allerdings wird es nicht passen ["foo",{"an":"object"}]

So {} ist spät in der Sortierreihenfolge, aber definitiv nicht letzte.

Antwort

1

Anstatt zu versuchen, den größten möglichen Wert für die Sekunden Elemente im Array Schlüssel zu finden, würde ich vorschlagen, stattdessen versucht, den dest möglichen Wert größer ist als die ersten zu finden: ?startkey=["some_customer_id"]&endkey=["some_customer_id\u0000"]&inclusive_end=false.

+0

Hinweis "inclusive_end" schützt vor dem lächerlichen Fall, in dem Sie tatsächlich einen Schlüssel der Form "some_customer_id \ u0000" haben, indem Sie keine Dokumente einschließen, die dem "endkey" im Ergebnis entsprechen. – user359996

0

CouchDB wird meistens in Erlang geschrieben. Ich glaube nicht, dass es eine obere Grenze für eine Tupelgröße einer Stringverbindung/zusammengesetzten Schlüsseln außer Systemressourcen geben würde (z. B. ein Schlüssel, so lange er den gesamten verfügbaren Speicher verwendet hat). Die Grenzen der CouchDB-Skalierbarkeit sind auf der CouchDB-Seite nicht bekannt. Ich würde vermuten, dass Sie Felder zu einem riesigen zusammengesetzten Primärschlüssel hinzufügen könnten und das einzige, was Sie daran hindern würde, sind Systemressourcen oder harte Grenzen wie maximale Integer-Größen auf der Zielarchitektur.

Da CouchDB alles unter Verwendung von JSON speichert, ist es wahrscheinlich auf die größten Zahlenwerte des ECMAScript-Standards beschränkt. Alle Zahlen in JavaScript werden als Gleitkomma-IEEE 754-Double gespeichert. Ich glaube, das 64-Bit-Double kann Werte von - 5e-324 bis + 1.7976931348623157e + 308 darstellen.

+0

Vielleicht war ich nicht klar genug. Die ID für diesen Kunden ändert sich nicht zwischen den Min- und Max-Werten. CouchDB erlaubt jedoch zusammengesetzte Schlüssel. Es wird zuerst beim ersten Eintrag (Konstante hier und gleich "some_customer_id") angeordnet, dann beim zweiten Eintrag (null für den Startschlüssel, 2 oder {} für den Endschlüssel) und so weiter. Ich frage mich, ob (und warum) {} der maximal mögliche Wert für einen Schlüssel in der Bestellung von CouchDB ist. –

+0

Ich denke, das Problem ist in meinem Fragetitel - ich werde für Klarheit umbenennen. –

+0

Oh, ich habe nicht gesehen, dass Sie über zusammengesetzte Schlüssel sprechen. Es scheint einige Einschränkungen auf CouchDB zu geben. Ich bezweifle, dass es eine feste Grenze für die Größe des Tupels für den zusammengesetzten Schlüssel gibt. Ich glaube, dass Systemressourcen für einige db-Operationen getestet werden würden, wenn Sie eine Tabelle mit Tausenden von Feldern und Hunderten von Feldern als Teil des zusammengesetzten Index erstellen. –

0

Es scheint, als wäre es schön, ein Feature zu haben, bei dem endKey inklusive statt exklusiv sein könnte.

+0

Eigentlich ist "endkey" standardmäßig inklusive. Sie müssen "endkey_inclusive = false" angeben, um exklusives Verhalten zu erhalten. – user359996

0

Diese den Trick tun sollten:

?startkey=["some_customer_id"]&endkey=["some_customer_id", "\uFFFF"] 

Dies sollte alles enthalten, die weniger mit einem Zeichen beginnt als \ uFFFF (alle Unicode-Zeichen)

+2

Ich glaube nicht. Der Artikel, den Sie verlinkt haben, besagt, dass alle Strings vor allen Arrays stehen, die wiederum vor allen Hashes stehen. Also ["some_customer_id", "\ uFFFF"] ist "kleiner als" ["some_customer_id", {}]. –

+0

Wie wäre es mit:?key = ["some_customer_id"] & include_docs = true – bogphanny

+0

Dies ist keine relationale Datenbankabfrage. Das Komma ist keine implizite Konjunktion. Alle für diese Ansicht ausgegebenen Schlüssel sind aus zwei Elementen bestehende Arrays. Ihre Abfrage würde also keine Ergebnisse liefern. – user359996

2

Ich habe zwei Gedanken.

Verwenden Zeitstempel

Statt einfach 0 und 1 für die Kollation Verhalten verwenden, einen Zeitstempel verwenden, die der Datensatz erstellt wurde (vorausgesetzt, sie sind Teil der Datensätze sind) ein la [doc._id, doc.created_at]. Dann könnten Sie Ihre Ansicht mit einem Startschlüssel von genügend frühem Datum abfragen (die Epoche würde wahrscheinlich funktionieren) und einem Endschlüssel von "jetzt", zB date +%s. Dieser Schlüsselbereich sollte immer alles enthalten, und er hat den zusätzlichen Vorteil, nach Datum zu sortieren, was Sie wahrscheinlich sowieso wollen.

oder, keine Sorge nur nicht darüber

Sie könnten nur Index durch die customer_id und nichts mehr. Dies hätte den Vorteil, dass nur mit key=<customer_id> abgefragt werden kann. Sicher, die Datensätze werden nicht sortiert, wenn sie zurückkommen, aber ist das ein Problem für Ihre Bewerbung? Wenn Sie nicht viele Datensätze erwarten, wäre es wahrscheinlich trivial, den Kundeneintrag einfach aus der Liste zu entfernen, sobald Sie die Daten von Ihrer Anwendung erhalten haben.

Zum Beispiel in Ruby:

customer_records = records.delete_if { |record| record.type == "customer" }

Sowieso ist der Zeitstempel wahrscheinlich die attraktivere Lösung für Ihren Fall.