2008-11-23 13 views
42

W jaki sposób uzyskać informacje dotyczące implementacji zapytań wymaganych do stronicowania?Paginacja w CouchDB?

Zasadniczo, gdy pierwsza strona jest żądana, uzyskaj pierwsze 5 wpisów. Na stronie 2, uzyskaj następne 5 i tak dalej.

Mam zamiar użyć tego przez moduł couchdb-python, ale to nie powinno mieć znaczenia dla implementacji.

Odpowiedz

31

CouchDB Guide ma dobrą dyskusję paginacji, w tym wiele przykładowy kod tutaj: http://guide.couchdb.org/draft/recipes.html#pagination Oto ich algorytm:

  • Zapytanie rows_per_page + 1 wiersze z widoku
  • Pokaż rows_per_page wiersze, sklep ostatni wiersz jako next_startkey
  • Jako strona informacyjna, zachować startkey i next_startkey
  • Użyj next_* wartości tworzyć następnego linku i użyć innych do tworzenia linka

N.B .: właściwy sposób pobierają strony w CouchDB jest poprzez podanie klucza wyjściową, a nie wskaźnik wyjścia jak ty może myśleć. Ale skąd wiesz, od czego zacząć drugą stronę?Sprytne rozwiązanie: "Zamiast żądać 10 wierszy dla strony, żądasz 11 wierszy, ale wyświetlasz tylko 10 i używasz wartości w 11 wierszu jako klucza startowego dla następnej strony."

Jeśli spodziewasz się, że wiele dokumentów będzie emitować identyczne klucze, musisz dodatkowo użyć numeru startdocid, aby prawidłowo je paginować. Powodem jest to, że sama startkey nie wystarczy, aby jednoznacznie zidentyfikować wiersz. Te parametry są bezużyteczne, jeśli nie podajesz startkey. W rzeczywistości CouchDB najpierw przyjrzy się parametrowi startkey, a następnie użyje parametru startdocid, aby ponownie zdefiniować początek zakresu, jeśli wiele potencjalnych wierszy z widokiem ma ten sam klucz, ale inne identyfikatory dokumentu. To samo dotyczy .

+2

Problem z tym podejściem polega na tym, że nie można tak naprawdę kliknąć poprzedniego kilka razy, tylko raz. Musisz albo ręcznie indeksować WSZYSTKIE możliwe pierwsze na stronie, gdy przejdziesz do następnych stron, albo możesz wrócić tylko 1 stronę, a potem nie masz żadnych informacji, aby przejść do poprzedniej innej strony. – for3st

+0

Dla tych, którzy potykają się tutaj, a także napotykają na dylemat @ for3st, naturalne właściwości tablicy pomagają rozwiązać ten problem. Przez 'push()' na poprzedniej stronie uruchom '_id' na tablicy możesz łatwo pop()' tablicę '_id' po kliknięciu poprzedniego. Co najwyżej wszystko, co musisz zrobić, to śledzić tablicę liczb całkowitych. – wootencl

1

To co mam wpadł do tej pory - aby uzyskać identyfikatory wszystkich stanowisk, a następnie pobierać rzeczywiste przedmioty na pierwszym x liczba identyfikatorów ..

To nie jest strasznie wydajny, ale bardziej, niż pobieranie wszystkich postów, a następnie wyrzucanie większości z dala. To powiedziawszy, ku mojemu zaskoczeniu, wydawało się, że działa dość szybko - przeprowadziłem 100-krotną metodę posthelper.page() i zajęło to około 0,5 sekundy.

nie chciałam odpowiedzieć w ten rzeczywisty pytanie, więc nie wpłynie na odpowiedź tyle - oto kod:

allPostsUuid = """ 
function(doc) { 
if(doc.type == 'post'){ 
    emit(doc._id, null); 
} 
} 
""" 

class PostsHelper: 
    def __init__(self): 
     server = Server(config.dbhost) 
     db = server[config.dbname] 
     return db 


    def _getPostByUuid(self, uuid): 
     return self.db.get(uuid) 

    def page(self, number = 1): 
     number -= 1 # start at zero offset 
     start = number * config.perPage 
     end = start + config.perPage 

     allUuids = [ 
      x.key for x in self.db.query(allPostsUuid) 
     ] 
     ret = [ 
      self._getPostByUuid(x) for x in allUuids[start : end] 
     ] 

     if len(ret) == 0: 
      raise Error404("Invalid page (%s results)" % (len(allUuids))) 
     else: 
      return ret 
13

CouchDB HTTP View API daje wiele możliwości, aby zrobić stronicowania efektywne .

Najprostszą metodą byłoby użycie startkey i count. Liczba to maksymalna liczba pozycji CouchDB zwróci dla tego żądania widoku, coś, co należy do twojego projektu, a klucz startowy to miejsce, w którym chcesz uruchomić CouchDB. Gdy poprosisz o widok, pokaże Ci również, ile wpisów istnieje, pozwalając obliczyć, ile stron będzie tam, jeśli chcesz pokazać to użytkownikom.

Tak więc pierwsze żądanie nie określało klucza startowego, a jedynie liczbę wpisów, które chcesz wyświetlić. Następnie możesz zanotować klucz ostatniego zwróconego zwrotu i użyć go jako klawisza startowego dla następnej strony. W tej prostej formie uzyskasz nakładkę, w której ostatni wpis jednej strony jest pierwszym z następnego. Jeśli nie jest to pożądane, po prostu nie należy wyświetlać ostatniego wpisu strony.

Prostszym sposobem jest użycie parametru pominięcia do opracowania dokumentu początkowego dla strony, jednak należy ostrożnie stosować tę metodę. Parametr pominięcia powoduje po prostu, że wewnętrzny silnik nie zwraca zwracanych pozycji, które iteruje. Chociaż daje to pożądane zachowanie, jest znacznie wolniejsze niż znalezienie pierwszego dokumentu dla strony według klucza. Im więcej dokumentów zostanie pominiętych, tym wolniejsze będzie żądanie.

+0

Aha! Z podanej strony: parametr count można połączyć z "skip = liczba wierszy do pominięcia". Idealny. – dbr

+0

Dodałem powyższe informacje do twojej odpowiedzi (dla mojego odniesienia, jeśli nic więcej), mam nadzieję, że nie masz nic przeciwko! – dbr

+2

Edytowałem to jeszcze raz. Używanie pominięcia nie jest dobrym sposobem na to, w większości przypadków. – Kerr