Pagina Web: raccolta casuale di elementi paginati recuperati tramite rest api call

2

Uso di .Net web api

Ho una pagina web che esegue il rendering di una raccolta di elementi in base ai valori dei filtri applicati tramite una chiamata ajax a un endpoint di API.

Gli elementi sono paginati in modo che se l'utente scorre verso il basso di una pagina, viene effettuata un'altra chiamata ajax all'api con il numero di pagina richiesto per il successivo set di elementi.

Ho appena ricevuto una richiesta di randomizzare tutti questi elementi ogni giorno.

Il problema ovvio qui è il paging ajax: ogni chiamata recupera il successivo gruppo di elementi che al momento è facile in quanto l'ordine di tali elementi non cambia. Quindi, se stiamo randomizzando, non posso semplicemente randomizzare ogni chiamata.

Quindi suppongo di aver bisogno di una sorta di memorizzazione nella cache ...

Questi sono pensieri fino ad ora:

  1. A mezzanotte, tutti gli elementi vengono caricati nella cache con una sorta di chiave di versione basata sulla data (in base all'ora del server).
  2. Tutte le chiamate client che sono elementi della pagina 1 otterranno sempre l'ultima versione della cache utilizzando la chiave basata sulla data. La risposta della pagina 1 restituirà la chiave di cache al client (insieme ai dati) in modo che eventuali chiamate per pagine superiori a 1 richiederanno la chiave di versione cache.
  3. Affrontare la possibilità che un utente effettui una richiesta di pagina 1 all'API alle 23:59:59 e quindi una richiesta di pagina 2 dopo la mezzanotte alle 00:00:30 potremmo scadere delle versioni della cache dopo 36 ore. Tuttavia, la nuova versione della cache viene creata ogni 24 ore a mezzanotte.

Questa è la direzione generale che sto considerando.

Qualcuno ha parole sagge?

    
posta wingyip 22.04.2018 - 15:14
fonte

3 risposte

0

Potresti includere qualche chiave univoca per ogni elemento già caricato e postare questo con la nuova richiesta Ajax e quindi selezionare alcuni elementi casuali tranne quelli nella lista ricevuta. Qualcosa come

SELECT top 10 * from myTable where Not Id in ('id1','id2'...) order by myRandomizer
    
risposta data 22.04.2018 - 23:12
fonte
0

So I guess I need some sort of caching...

Sebbene l'idea della cache non sia impossibile, ti suggerisco di prendere una strada più facile. Le cache con logica personalizzata sono spesso difficili da implementare correttamente o eseguono il debug in caso di problemi.

I have just had a request to randomise all of these items daily.

La parte "quotidiana" attirò la mia attenzione. Se dovessi randomizzare sempre l'elenco, ti ritroverai con una logica complicata (come hai già scoperto).

Tuttavia, dato che lo shuffle si verifica in un ciclo relativamente lento, esiste un modo più semplice per farlo.

Dato che hanno chiesto un rimescolamento giornaliero, deduco che in particolare vogliono mantenere lo stesso ordine durante lo stesso giorno, per ogni utente. Questo metodo più semplice significa meno spese generali per garantire che tutti lavorino con lo stesso ordine mescolato nello stesso giorno.

  1. Aggiungi una ShuffledOrder proprietà int alla tua classe

public class Person
{
    public string Name { get; set; }
    public int ShuffledOrder { get; set; }
}

  1. Crea un processo che viene eseguito ogni mezzanotte , che mischia l'ordine. L'idea è che finisci sempre con una sequenza ShuffleOrder che va da 1 a N (dove N è la quantità di entità), ad esempio:

  Name  |  ShuffledOrder
==========================
   Tim  |      3
   Tom  |      2
   Joe  |      1
   Bob  |      4

Un semplice esempio di algoritmo shuffling:

var rnd = new Random();
var people = db.People.ToList();
int shuffleOrder = 1;

foreach(var person in people.OrderBy(p => rnd.Next())
{
    person.ShuffledOrder = shuffleOrder++;
}

db.SaveChanges();

Si noti che questo è un esempio semplificato per mostrare la logica dello shuffling. Considerazioni sulle prestazioni (ad esempio non caricare una tabella potenzialmente massiccia in memoria) sono state omesse per mantenere l'esempio semplice.

  1. Quando recuperi elementi dalla tabella, li ordina sempre in base al loro ShuffleOrder

var pagedList = db.People
                       .OrderBy(p => p.ShuffledOrder)
                       .Skip(pageIndex * pageSize)
                       .Take(pageSize)
                       .ToList();

Riepilogo

  • Impostare l'ordine mescolato in pietra ti assicura di mantenere l'ordine mescolato per tutto il tempo che desideri.
  • Questo approccio non è influenzato negativamente da nessuna logica di filtro aggiuntiva che potresti avere.
  • Mi aspetto che questo sia più performante del rifare il randomizzatore per ogni chiamata (anche se il randomizzatore è seminato con la data odierna)
  • Evita il caching, che tende a complicare lo sviluppo e il debug.
risposta data 20.09.2018 - 08:12
fonte
0

Non rendere il tuo DBE ridondante facendo il suo lavoro (memorizzazione nella cache) e non complicare eccessivamente il client con i dettagli di implementazione (chiavi della cache).

Il tuo DBE ha già gli strumenti per gestire una buona cache (eventualmente anche per l'invalidazione della cache), creare una vista ordinata usando la data corrente come criteri e effettuare l'impaginazione anziché la tabella.

Le cache e gli indici DBE faranno il resto. Puoi prima provare con:

  • semplice ORDER BY nella query durante la lettura della vista, ma non tutti i DBE potrebbero essere abbastanza efficienti per questo caso d'uso.
  • se supportato, usa una display_index nella vista, calcolata usando un numero casuale seminato con la data corrente su una query già ordinata da un'altra colonna stabile (ad esempio id ).

In ogni caso inizia con quello più semplice e misura (e sintonizza il tuo indice !!!)

    
risposta data 20.09.2018 - 09:09
fonte

Leggi altre domande sui tag