Quali sono le soluzioni e i compromessi per mantenere la consistenza dei risultati di ricerca in un'applicazione web

4

Considera un'applicazione web con una funzione di ricerca personalizzata che deve visualizzare i risultati in modo paginato (venti per pagina con un massimo di centinaia di migliaia di risultati totali) e la possibilità di eseguire il drill-down sui singoli risultati che mantengono i link precedenti / precedenti per navigare tra i risultati.

La riesecuzione della ricerca su ogni richiesta di pagina per ottenere i risultati appropriati per quella pagina di dati può essere troppo costosa (fino a 15 secondi per ricerca). Inoltre, poiché i dati sottostanti possono cambiare frequentemente (ad es. Aggiunta di nuovi risultati), la riesecuzione potrebbe causare il comportamento incoerente della funzionalità successiva / precedente (ad es. Gli stessi risultati che riappaiono in una pagina successiva dopo essere stati visualizzati in una pagina precedente ).

Quali opzioni esistono per garantire che i risultati della ricerca possano essere visualizzati su più pagine in modo coerente e quali sono i compromessi che ciascuna opzione ha in termini di rete, CPU, memoria e requisiti di archiviazione?

EDIT: ho pensato che memorizzare nella cache i risultati della ricerca delle query fosse una necessità ovvia. La domanda è in realtà chiedendo su dove mettere in cache il set di risultati e quali compromessi potrebbero esistere per ciascuno. Ad esempio, la memorizzazione degli ID delle entità nel set di risultati sul client o la memorizzazione degli ID delle entità stesse nella sessione degli utenti sul server Web o in una tabella temporanea nel database. Non sto cercando specificamente una singola soluzione poiché diversi scenari potrebbero comportare approcci diversi (e tale domanda sarebbe più adatta per stackoverflow.com piuttosto che qui), ma più di un confronto di design tra i possibili approcci.

    
posta iammichael 19.12.2010 - 18:44
fonte

5 risposte

2

È molto comune per i motori di ricerca solo ripristinare le ricerche per arrivare alla "pagina 2".

La memorizzazione dei risultati di ricerca per utente può rapidamente trasformarsi in un disastro di memoria / dati. Estrarre tutti i risultati dall'indice di ricerca e archiviarli può rapidamente diventare più lento, quindi basta eseguire nuovamente la query per cercare "pagina" / visualizzazione.

Se riesci a rimandare l'indicizzazione a un lavoro notturno, potresti aggirare il problema del disallineamento.

Alcuni componenti di indicizzazione possono anche supportare "generazioni di indici" quando puoi ri-interrogare una ricerca specificando quale generazione di indice usare. L'output sarebbe sempre lo stesso e allineare.

    
risposta data 09.05.2011 - 02:00
fonte
1

Non sei sicuro di quale sia il tuo motore di ricerca sottostante, ma i risultati di ricerca 15s? Meh.

Non minimizzare le tue preoccupazioni, ma usando pacchetti come Lucene e Solr può togliere la maggior parte di questi mal di testa. Diamine, anche qualcosa come MongoDB potrebbe risolvere questi problemi. Sono costruiti per gestire questi scenari in modo molto più efficiente.

    
risposta data 26.01.2011 - 09:48
fonte
1

Un modo in cui puoi ottenere questo risultato, a seconda di quanto traffico ricevi, sarebbe di impostare (se non lo hai già) Edge Side include con la parola chiave della query e i parametri di paging che fanno parte dell'URL. In questo modo ulteriori query sulle stesse parole chiave non colpiranno nemmeno il tuo server delle applicazioni.

È possibile configurare il tempo di scadenza su include per determinare per quanto tempo si desidera memorizzare i risultati. Un'altra opzione sarebbe quella di aggiungere un parametro all'URL che è possibile modificare in-application ogni volta che si desidera aggiornare la cache.

    
risposta data 29.04.2011 - 19:37
fonte
0

Rendi le tue ricerche immutabili

La maggior parte dei potenziali problemi citati può essere resa irrilevante semplicemente memorizzando nella cache i risultati di una particolare ricerca . In altre parole, non rieseguire la ricerca ogni volta che visualizzi la pagina dei risultati successiva.

In una tipica applicazione Web, una funzione di ricerca assume la forma di un risultato di una query, in cui ogni pagina viene consegnata in base alle esigenze, utilizzando alcune funzioni di supporto. Quando esegui la ricerca, devi memorizzare nella cache i risultati della ricerca da qualche parte e consegnare ogni pagina della ricerca come richiesto.

Nel mondo Microsoft .NET, questo sarebbe fatto usando Skip() e Take() funzioni su un Linq query. Il codice potrebbe essere simile a questo:

var searchResults = from tableToSearch 
                    where myConditions 
                    select someFieldsToDisplay;

var pageResults = searchResults.Skip((requestedPageNumber- 1) * resultsPerPage)
                               .Take(resultsPerPage)

Quindi searchResults diventa il set di record contenente i risultati della ricerca e pageResults contiene i record richiesti da quei risultati di ricerca per quella particolare pagina.

Nella maggior parte delle applicazioni, la freschezza dei risultati di ricerca è un non-problema, a patto che sia chiaro all'utente che, se vogliono risultati più vecchi di due o tre minuti, possono semplicemente eseguire un nuovo marchio ricerca.

    
risposta data 19.12.2010 - 23:27
fonte
0

Provare metodi alternativi di ricerca o indicizzazione per migliorare le prestazioni di ricerca sarebbe la prima cosa da provare in una situazione del genere. Ma dato che non risponde direttamente alla domanda, ed è stato mesi senza una risposta completa, ho intenzione di fare del mio meglio per rispondere a me stesso (rendendolo community wiki dato che sono sicuro che questa risposta può ancora essere migliorata) .

Richiediamo che i risultati di una query vengano presentati all'utente su un intervallo di più pagine Web e che l'intero set di risultati sia coerente tra le pagine. Come la domanda originale implica e la domanda modificata conferma, sappiamo che i risultati della ricerca iniziale devono essere memorizzati nella cache per garantire questa coerenza (la freschezza è meno importante della coerenza). Ci sono tre posti principali in un'applicazione web in cui i risultati potrebbero essere memorizzati nella cache.

La prima opzione è memorizzare nella cache i risultati nella memoria del server . In questo caso, la query viene eseguita e gli identificatori per tutti i risultati vengono salvati di solito in un'area di memoria specifica dell'utente come HttpSessionState di ASP.NET o HttpSession di Java {1}. Il sottoinsieme di identificativi per la pagina di dati richiesta viene quindi estratto da questo set di risultati e utilizzato per caricare i dati effettivi per il ritorno al browser Web dell'utente. Poiché ogni nuova pagina viene richiesta, lo stesso set di identificatori viene utilizzato per estrarre i dati per tali pagine aggiuntive.

L'opzione successiva è memorizzare nella cache i risultati nel database o altra memoria persistente. Gli identificatori risultanti dall'esecuzione della query vengono riscritti nel database in una tabella di attesa temporanea che può essere richiesta nuovamente per ogni pagina richiesta per determinare gli identificatori delle entità che devono essere restituite al browser dell'utente, seguite da un carico dell'effettivo i dati.

L'ultima opzione sarebbe quella di impacchettare l'elenco completo degli identificatori dei risultati di ricerca e memorizzarli sul client . Quando si richiedono pagine aggiuntive, il client può inviare l'intero elenco al server per l'elaborazione per determinare quali record di risultati caricare e visualizzare. Con un client leggermente più pesante (ad esempio javascript, flash, ecc.), Il client stesso potrebbe determinare quali record di risultati sono necessari dai propri identificatori, richiedere quelli dal server e aggiornare il display in modo appropriato senza dover inviare l'elenco completo a il server.

I compromessi qui sono per lo più intuitivi. La memorizzazione in memoria richiede memoria sufficiente per archiviare tutti i risultati di ricerca dell'utente attivo. Potrebbero esserci alcune sfide con ricerche simultanee multiple da parte dello stesso utente (ad esempio due finestre del browser aperte), ma che potrebbero essere risolte con un identificatore di ricerca univoco come chiave per i risultati all'interno della memoria (anziché digitare solo l'identificativo utente o utilizzando una chiave fissa nell'archivio dati di sessione specifico dell'utente). Anche se probabilmente la più semplice da implementare, potrebbe essere rapidamente problematica se non esiste un modo semplice per identificare quando un utente non è più attivo ei risultati possono essere rimossi dalla memoria o se il numero di risultati che il numero di utenti può combinare per superare la memoria del server disponibile.

La memorizzazione dei risultati nel database aggiunge un sovraccarico in più per mantenere i risultati e ri-interrogare per gli identificatori giusti, ma dovrebbe essere minimo. Sarebbe necessario un qualche tipo di lavoro di pulizia per eliminare i risultati di ricerca obsoleti quando gli utenti non sono più attivi e i loro risultati non sono più necessari.

La memorizzazione dei risultati sul client elimina gran parte del sovraccarico dell'infrastruttura applicativa inerente alle altre opzioni (memoria e archiviazione), ma richiede invece una maggiore larghezza di banda che può influire sui tempi di caricamento delle pagine a un livello inaccettabile (specialmente sul carico iniziale di tutti gli identificatori). Il server potrebbe comunque necessitare di ulteriori lavori per garantire che i dati richiesti dal client siano validi e non un client canaglia che richiede dati arbitrari a cui non dovrebbe avere accesso (ciò potrebbe probabilmente essere ottenuto con la crittografia delle chiavi o crittograficamente strong hash per garantire che i dati non siano modificati dal client)

{1} Le sessioni utente di solito possono essere configurate per essere archiviate in un database invece che nella memoria del server. La prima opzione riguarda solo le situazioni in cui viene utilizzata la memoria del server per archiviare i risultati. Altrimenti, stai esaminando la seconda opzione in cui la sessione dell'utente è un livello più amichevole oltre a memorizzare i dati nel database (ad esempio la seconda opzione.

    
risposta data 21.03.2011 - 23:36
fonte

Leggi altre domande sui tag