Punto di progettazione per la ricerca di prodotti e il completamento automatico utilizzando la ricerca elastica?

4

Devo implementare la ricerca di prodotto usando la ricerca elastica in modo simile a quanto avviene su qualsiasi sito di e-commerce scalabile. Sto pianificando l'algoritmo di seguito per questo

  1. Ogni volta che il prodotto viene aggiunto al sistema, prima aggiungilo nel DB e poi nel server ES. ES creerà l'indice sul documento fornito e quindi conserverà sia l'indice che il documento in memoria. Quindi sarà come scrivere nella cache (dove con Cache qui intendevo gli indici e il documento in memoria.) Da non confondere con la cache dei valori chiave come Redis / memcache).
  2. Dì, il mio documento in DB ha 30 campi, ma ho bisogno di cercare solo su tre campi (nome, descrizione e tipo). Quindi ES avrà 4 (3 + 1) campi. 3 sono campi ricercabili e il quarto campo è l'id della chiave primaria che rappresenta la chiave univoca in DB
  3. ES crea l'indice su 3 campi internamente mentre lo aggiunge e lo mantiene in memoria.
  4. Durante la ricerca, la query di ricerca passerà al server ES per multimatch e recupererà il risultato pertinente con l'ordine in base al fattore di aumento della query.
  5. Il risultato della ricerca conterrà l'id del campo che rappresenta la chiave primaria del DB con la quale possiamo recuperare ulteriormente i dettagli del prodotto dal DB in base al primario ID chiave.
  6. Abbiamo bisogno di reindicizzare nuovamente i 3 campi durante l'avvio del server ES. Per questo preleverò i dati dal DB durante l'avvio e lo fornirò a ES.

Con questo design tutto il campo ricercabile sarà memorizzato nella cache in memoria sotto il sistema in qualsiasi momento e non ci sarà cache miss e il sistema dovrà colpire DB. Questo design sembra buono o mi manca qualcosa qui?

Completamento automatico Lo stesso disegno che possiamo usare per il completamento automatico quando l'utente inizia a digitare. Ad esempio, quando l'utente inizia a digitare, dire 3 lettere, la query andrà al back end e al di sopra del design funzionerà anche lì. L'unica differenza sarà che restituirà solo risultati limitati per i primi 10 risultati invece di restituire tutti i risultati.

Pubblicherà una domanda separata sulla mia domanda / pensieri su come renderlo scalabile.

    
posta user3198603 19.08.2018 - 09:40
fonte

1 risposta

1

Come hai scritto questa domanda, descrive l'utilizzo standard per un motore di ricerca: indichi i campi da cercare, quindi esegui query su quei campi.

Un motore di ricerca, tuttavia, è non una cache , anche se capita di memorizzare i suoi indici in memoria. Se si desidera una ricerca rapida basata su ID per i dati, è necessario utilizzare una cache effettiva come Redis o Memcached.

Lungo queste linee, il punto 6 si applica solo all'inizializzazione del tuo cluster ES (o alla reinizializzazione se si sceglie di apportare modifiche importanti al database). Durante il normale funzionamento, un cluster ES scrive gli indici sul disco.

L'unica cosa a cui devi pensare è quando aggiornerai il tuo server ES a causa delle normali modifiche al database. Alcune opzioni:

  • Esegue l'aggiornamento ES nella stessa transazione dell'aggiornamento del database. Ciò aumenterà il tempo necessario per l'aggiornamento del database (aumentando così la possibilità di contesa del blocco), oltre a causarne il fallimento in caso di problemi con il server ES.
  • Esegue l'aggiornamento ES dopo la transazione del database ma all'interno della stessa richiesta utente. Rompe l'accoppiamento tra database e motore di ricerca, ma significa che gli aggiornamenti del database non possono essere indicizzati. I ritardi nell'aggiornamento della ricerca saranno visibili all'utente.
  • Eseguire l'aggiornamento ES in modo asincrono per l'aggiornamento del database. Consente il clustering di aggiornamenti ES, che migliora il suo comportamento, ma introduce un ritardo tra il momento in cui il database viene aggiornato e il tempo in cui tali aggiornamenti appaiono sono ricercabili.

Per le seconde due opzioni, aggiungerei un campo indexed_at alla riga del database, accanto a updated_at (tu fai usi updated_at e updated_by , giusto?), quindi che puoi rilevare discrepanze tra le transazioni del database e gli aggiornamenti di ricerca.

    
risposta data 03.09.2018 - 16:05
fonte

Leggi altre domande sui tag