Come evitare di mostrare i risultati della pagina 1 a pagina 2?

3

Ecco lo scenario:

  1. Sto mostrando all'utente (chiamiamolo UtenteA) 10 elementi per pagina , ordinandoli per data (prima la più recente) .

  2. Come utentePer visualizzare ancora la pagina 1, un altro utente (chiamiamolo UserB) pubblica un nuovo elemento.

  3. Quindi, UtenteA ha deciso di fare clic sulla pagina 2. Ora UtenteA è sorpreso di vedere l'ultimo elemento che è apparso nella pagina 1 viene mostrato di nuovo come il primo elemento nella pagina 2.

Come risolvere questo problema? (Penso che ci siano diversi approcci per risolvere questo problema).

Per chiarire, questa è la mia domanda:

select * from items order by publish_date desc limit <(PAGE_NUMBER - 1) * 10>, 10

Da notare : "Lo scorrimento infinito" non è una soluzione, perché dietro le quinte lo scorrimento infinito è semplicemente l'impaginazione in cui viene richiesta automaticamente la pagina successiva.

Scenario alternativo:

  1. Sto mostrando all'utente (chiamiamolo UtenteA) 10 elementi per pagina , ordinandoli per data (prima la più recente) .

  2. Come utentePer visualizzare ancora la pagina 1, un altro utente (chiamiamolo UserB) elimina un elemento (supponiamo che l'elemento eliminato sia l'ultimo elemento nella pagina 1).

  3. Quindi, UtenteA ha deciso di fare clic sulla pagina 2. Ora UtenteA vede 10 elementi della pagina 2, ma non sa che l'ultimo elemento della pagina 1 è diverso ora (perché è stato eliminato, quindi il primo l'elemento della pagina 2 viene visualizzato come ultimo elemento nella pagina 1). Quindi Utente manca la visualizzazione di 1 elemento.

posta evilReiko 21.12.2016 - 08:08
fonte

3 risposte

4

C'è un altro tipo di impaginazione che è più difficile da implementare, ma farà quello che vuoi, di solito si adatta allo scorrimento infinito ed è più performante.

Fondamentalmente usi i dati dell'ultima riga come parametro della tua query:

SELECT * FROM sales
WHERE sale_date < ? ORDER BY sale_date DESC FETCH FIRST 10 ROWS ONLY

Dove ? sarà il valore del tuo ultimo sale_date.

Si chiama Impaginazione utilizzando il metodo di ricerca .

Maggiori informazioni a riguardo qui: link

Tuttavia, questo non può essere implementato liberamente rispetto al metodo limite in quanto è necessario assicurarsi di modificare i parametri della query in base ai filtri e agli ordini correnti degli utenti. Se la tua pagina è una semplice pagina di ricerca con solo pochissimi filtri o nessuno, questo sarà fattibile.

Se hai una logica di ricerca complessa, mantieni il limite e, come detto Robert Harvey, è di progettazione. Quello che puoi fare è lasciare che l'utente abbia una pagina o più di 10 righe su ogni pagina.

    
risposta data 21.12.2016 - 09:26
fonte
2

Fondamentalmente, la tua query deve considerare quali elementi sono già stati visti. Poiché la posizione degli articoli nell'ordine non è stabile (è possibile inserire nuovi elementi all'inizio), è necessario utilizzare un modo diverso per identificare i limiti di ciascuna "pagina".

Fortunatamente, la posizione relativa degli articoli nel tuo ordinamento sembra essere stabile (se un oggetto era prima di un altro oggetto, rimarrà in questo modo). Pertanto, dovrebbe essere sufficiente inviare l'ultimo elemento della pagina corrente e richiedere i successivi X elementi dopo.

Questo probabilmente ridurrà le prestazioni, quindi esegui alcuni benchmark e chiediti se il problema conta davvero, o se ci si può aspettare che gli utenti lo affrontino (ci occupiamo di esperienze simili su altri siti).

Come accennato, potresti anche incorrere in problemi se gli articoli vengono rimossi (dato che potresti finire per cercare un articolo che non esiste più), quindi se hai quel requisito ti consiglio semplicemente di contrassegnarli come cancellati e rimuovere tutto bit di informazioni ad eccezione di ID e data di pubblicazione, quindi ignorarli nella query.

    
risposta data 21.12.2016 - 08:46
fonte
1

Reddit ha dovuto risolvere anche questo, perché il contenuto è stato aggiunto rapidamente. Se osservi la loro impaginazione, troverai URL come questi:

?count=26&before=t3_5jfkqr  (link from page 2 to page 1)
?count=50&after=t3_5j99dj   (link from page 2 to page 3)

Dove 5jfkqr e 5j99dj sono rispettivamente il primo e l'ultimo elemento della pagina corrente e count la posizione corrente di quell'oggetto stesso.

Utilizzando i parametri before e after gli elementi possono essere recuperati in questo modo:

select * from items where publish_date < (
  select publish_date from items where id=<AFTER>
) order by publish_date desc limit <PAGE_SIZE>

select * from items where publish_date > (
  select publish_date from items where id=<BEFORE>
) order by publish_date asc limit <PAGE_SIZE>

(i risultati della seconda query sono in ordine inverso)

Numeri di pagina

Il parametro count viene utilizzato per tenere traccia del numero di pagina.

Ora, reddit mostra solo i link "prev" e "next", ma questo può essere esteso con un parametro skip . Ad esempio per collegare alla seconda pagina successiva:

?count=50&after=t3_5j99dj&skip=25   (link from page 2 to page 4)

Questo potrebbe essere trasformato in una query come:

select * from items where publish_date < (
  select publish_date from items where id=<AFTER>
) order by publish_date desc limit <SKIP>, <PAGE_SIZE>

Limitazioni

Se il primo o l'ultimo elemento della pagina corrente viene cancellato, l'impaginazione si interromperà. Pertanto, assicurati che gli elementi eliminati rimangano nel database con un flag deleted , anziché rimuoverli interamente, almeno per un periodo di tolleranza.

    
risposta data 22.12.2016 - 10:00
fonte

Leggi altre domande sui tag