2013-07-22 10 views
5

Sto ospitando un database mongodb per un servizio che supporta la ricerca full-text su una raccolta con 6,8 milioni di record.Ricerca indice testo MongoDB lenta per parole comuni nella tabella grande

L'indice di testo include dieci campi con pesi variabili.

index specification

La maggior parte delle ricerche prendono meno di un secondo. Alcune ricerche richiedono da due a tre secondi. Tuttavia, alcune ricerche richiedono 15 - 60 secondi! I casi di ricerca di 15-60 secondi non sono accettabili per la mia applicazione. Devo trovare un modo per velocizzare quelli.

La ricerca richiede 15-60 secondi quando le parole che sono molto comuni nell'indice vengono utilizzate nella query di ricerca.

Sembra che la funzione di ricerca del testo non supporti i parametri pigri. Il mio primo pensiero è stato quello di mettere in cache una lista delle 50 parole più comuni nel mio indice di testo e poi chiedere a mongodb di valutare quelle ultime (pigre) e in cima ai risultati filtrati restituiti dai parametri meno comuni. Spero che le persone siano ancora con me. Ad esempio, dire che ho una domanda "prodotti di cioccolato", in cui i prodotti sono comuni e il cioccolato è raro. Mi piacerebbe poter chiedere a mongodb di valutare prima "cioccolato" e poi filtrare quei risultati con il termine "prodotti". Qualcuno sa di un modo per raggiungere questo obiettivo?

Posso raggiungere lo scenario precedente omettendo le parole più comuni (ad esempio "prodotti") dalla query db e quindi riapplicando il filtro termine comune sul lato dell'applicazione dopo aver ricevuto record trovati da db. È preferibile che tutta la logica della query si verifichi nel database, ma sono aperta all'elaborazione lato applicazione per un pagamento della velocità.

Ci sono ancora alcuni buchi in questo disegno. Se un utente cerca solo termini comuni, non ho altra scelta che colpire il database con tutti i termini. Dalla lettura preliminare, deduco che non è raccomandato (o non supportato) avere più indici di testo (con nomi diversi) sulla stessa collezione. Il mio piano è di creare due tabelle identiche, ciascuna con i miei record di 6,8 milioni, con indici diversi, uno per le parole comuni e uno per le parole non comuni. Questo sembra kludgy e goffo, ma sono disposto a farlo per un aumento di velocità.

Qualcuno ha qualche idea e/o consigli su come accelerare questo sistema. Mi piacerebbe che l'elaborazione avvenga nel database il più possibile per mantenerla veloce. Sono sicuro che la mia piccola tabella di registrazione 6.8M non è la più grande che mongodb abbia mai visto. Grazie!

+0

È ora 2018 (5 anni più tardi), e mongodb ha ancora lo stesso identico problema :( – Nico

+1

a causa di questo in coppia con la significativa performance di mongo implementata, con la quale abbiamo determinato che l'uso di mongo in questo modo non era un uso primario "supportato" o "previsto", abbiamo deciso di abbandonare del tutto il mongo.piace per l'acqua fredda – kmehta

risposta

4

Bene, ho lavorato su questi problemi di prestazioni consentendo la ricerca full text di MongoDB per cercare in formato OR. Sto dando la priorità ai miei risultati mettendo a punto i pesi sui miei campi indicizzati e ordinando semplicemente per rank. Ottengo più risultati di quanto desiderato, ma non è un grosso problema perché i risultati ponderati che appaiono in alto saranno probabilmente consumati prima che il mio utente ottenga risultati meno rilevanti in basso.

Se qualcuno sta lottando con le prestazioni di ricerca di testo MongoDB utilizzando solo la ricerca AND, è sufficiente tornare a OR e controllare i risultati utilizzando i pesi. Funziona meglio.

hth

+3

Esattamente. Se usi i termini di ricerca tra virgolette (che credo sia ciò che intendi per formato AND), il testo di MongoDB la ricerca utilizzerà per prima cosa l'indice di testo su parole con stemmed, quindi controlla ogni documento per assicurarsi che (a) siano presenti entrambe le parole e (b) la versione non modificata delle parole sia identica ai termini citati che hai passato. molto meno performante rispetto all'altra opzione (non citando i termini), in cui viene utilizzato l'indice di testo e non c'è un secondo passaggio per ogni documento. prenditi cura dei risultati della classifica con entrambe le parole presenti sopra i risultati con una sola. – Amalia

0

Questo è il problema esattamente lo stesso da $ tutto contro $ a. $ utilizza solo l'indice per la prima parola chiave nell'array. Credo che tu stia vedendo lo stesso problema qui, motivo per cui l'OR a.k.a. IN funziona per te.