2013-01-20 10 views
5

tl; dr in Firebase Grund Paginierung Performing über startAt, endAt und limit furchtbar kompliziert ist, muss es einen einfacheren Weg geben.Paginieren chronologisch Kinder priorisiert Firebase

Ich baue eine Administrationsoberfläche für eine große Anzahl von Benutzereinreichungen. Meine anfängliche (und aktuelle) Idee ist, einfach alles abzuholen und Seitenumbrüche auf dem Client durchzuführen. Es gibt jedoch eine bemerkenswerte Verzögerung beim Abrufen von 2000+ Aufzeichnungen (die jeweils 5-6 kleine Anzahl/Zeichenkettenfelder enthalten), die ich einer Datennutzlast von über 1,5 MB zuschreibe.

Derzeit sind alle Einträge über push hinzugefügt, aber ich bin ein bisschen verloren, wie paginate durch die riesige Liste.

Um die erste Seite von Daten hole ich endAt mit einem limit von 5 bin mit:

ref.endAt().limit(10).on('child_added', function(snapshot) { 
    console.log(snapshot.name(), snapshot.val().name) 
}) 

, die in den folgenden Ergebnissen: Es

-IlNo79stfiYZ61fFkx3 #46 John 
-IlNo7AmMk0iXp98oKh5 #47 Robert 
-IlNo7BeDXbEe7rB6IQ3 #48 Andrew 
-IlNo7CX-WzM0caCS0Xp #49 Frank 
-IlNo7DNA0SzEe8Sua16 #50 Jimmmy 

Zum einen, um herauszufinden, wie viele Seiten Ich halte einen separaten Zähler, der aktualisiert wird, wenn jemand einen Datensatz hinzufügt oder entfernt.

Zweitens, da ich push bin mit habe ich keine Möglichkeit zu einer bestimmten Seite zu navigieren, da ich für eine bestimmte Seite bedeutet eine Schnittstelle den Namen des letzten Datensatz nicht wissen, wie dies derzeit nicht möglich ist:

Standard pagination controls

Um es einfacher zu machen, entschied ich mich dafür, einfach die nächsten/vorherigen Tasten zu haben, dies stellt aber auch ein neues Problem dar; wenn ich den Namen des ersten Datensatzes in dem vorherigen Ergebnis-Set verwenden, kann ich auf die nächste Seite mit dem folgenden Paginieren:

ref.endAt(null, '-IlNo79stfiYZ61fFkx3').limit(5).on('child_added', function(snapshot) { 
    console.log(snapshot.name(), snapshot.val().name) 
}) 

Das Ergebnis dieser Operation ist wie folgt:

-IlNo76KDsN53rB1xb-K #42 William 
-IlNo77CtgQvjuonF2nH #43 Christian 
-IlNo7857XWfMipCa8bv #44 Jim 
-IlNo78z11Bkj-XJjbg_ #45 Richard 
-IlNo79stfiYZ61fFkx3 #46 John 

Jetzt Ich habe die nächste Seite, außer dass es um eine Position verschoben ist, was bedeutet, dass ich mein Limit anpassen und den letzten Rekord ignorieren muss.

Um eine Seite zurückzugehen, muss ich eine separate Liste auf dem Client von jedem Datensatz, den ich bisher erhalten habe, aufbewahren und herausfinden, welcher Name an startAt übergeben werden soll.

Gibt es einen einfacheren Weg dies zu tun oder sollte ich einfach wieder alles holen?

Antwort

7

Wir arbeiten daran, eine "offset()" -Abfrage hinzuzufügen, um eine einfache Paginierung zu ermöglichen. Außerdem fügen wir einen speziellen Endpunkt hinzu, mit dem Sie die Anzahl der untergeordneten Objekte an einem Standort lesen können, ohne sie tatsächlich vom Server zu laden.

Beide werden aber ein bisschen dauern. In der Zwischenzeit ist die Methode, die Sie beschreiben (oder alles auf dem Client tun) wahrscheinlich Ihre beste Wette.

Wenn Sie eine Datenstruktur haben, die nur angehängt ist, können Sie beim Schreiben der Daten möglicherweise auch eine Paginierung durchführen. Zum Beispiel: Legen Sie die ersten 50 in/page1, legen Sie die zweite 50 in/page2, etc.

+2

Dank, offset() und count() lösen alle Seitenumbruch Probleme. –

+0

Gibt es ein Update darüber, wann diese Funktionen für die JavaScript-API freigegeben werden - insbesondere mit Unterstützung für AngularFire-Bindungen? –

+0

+1 für die Frage von @DanKanze. Das wäre großartig, besonders für AngularFire. – Jake

4

Ein anderer Weg, dies zu tun ist mit zwei Bäumen:

Baum von ids: { id1: id1, id2: id2, id3: id3 }

Baum der Daten: { id1 : ..., id2: ..., id3: ... }

anschließend können Sie den gesamten Baum von ids (oder einen großen Teil davon) an den Client laden, und Lust haben Paginierung mit das tr ee von ids.

2

Hier ist ein Hack für paginate in jeder Richtung.

// get 1-5 
ref.startAt().limit(5) 

// get 6-10 from 5 
ref.startAt(null, '5th-firebase-id' + 1).limit(5) 

// get 11-15 from 10 
ref.startAt(null, '10th-firebase-id' + 1).limit(5) 

Grundsätzlich ist es ein Hack für startAtExclusive(). Sie können alles bis zum Ende der ID.

Auch herausgefunden endAtExclusive() für rückwärts gehen.

// get 6-10 from 11 
ref.endAt(null, '11th-firebase-id'.slice(0, -1)).limit(5)... 

// get 1-5 from 6 
ref.endAt(null, '6th-firebase-id'.slice(0, -1)).limit(5)... 

Will mit diesem etwas mehr spielen, aber scheint mit Push-IDs zu arbeiten. Ersetzen Sie das Limit mit limitToFirst oder limitToLast, wenn Sie Firebase-Abfragen verwenden.