2016-07-05 65 views
15

sto usando MongoDB, e ho una raccolta di documenti con la seguente struttura:Indice Bounds su Mongo Regex Ricerca

{ 
    fName:"Foo", 
    lName:"Barius", 
    email:"[email protected]", 
    search:"foo barius" 
} 

Sto costruendo una funzione che eseguirà una ricerca espressione regolare sul campo search . Per ottimizzare le prestazioni, ho indicizzato questa raccolta nel campo di ricerca. Tuttavia, le cose sono ancora un po 'lente. Così mi sono imbattuto un explain() su una query di esempio:

db.Collection.find({search:/bar/}).explain(); 

Guardando sotto il piano vincente, compaiono i seguenti limiti indice usati:

"search": [ 
     "[\"\", {})", 
     "[/.*bar.*/, /.*bar.*/]" 
] 

Il secondo set ha un senso - che sta cercando da tutto ciò che contiene barra a tutto ciò che contiene bar. Tuttavia, il primo set mi sconcerta. Sembra che guardi nei limiti di "" incluso a {} esclusivo. Sono preoccupato che questo set di limiti extra stia rallentando la mia richiesta. È necessario mantenere? Se non lo è, come posso evitare che venga incluso?

+0

Ha lo stesso problema, hai trovato una spiegazione? – kirhgoff

+0

@kirhgoff Quale versione di mongoDB stai usando? – barbakini

+0

@kirhgoff cosa stai usando 'mongoDB native' o' mongoose'. Controlla questo - http://voidcanvas.com/mongoose-vs-mongodb-native/ –

risposta

5

Penso che sia proprio il modo in cui mongodb funziona con regex (vedere https://scalegrid.io/blog/mongodb-regular-expressions-indexes-performance/). Basta fare attenzione al valore nscanned/totalKeysExamined, se è troppo grande allora l'indice è inutile per la tua query.

Consulta anche: MongoDB, performance of query by regular expression on indexed fields

+0

Accetto, come indicato nella documentazione di MongoDB e in https://stackoverflow.com/a/33219393/8291949 se la tua espressione regolare non è una "espressione prefisso" mongo eseguirà la scansione completa delle chiavi nell'indice, quindi recupererà i documenti corrispondenti (che dovrebbero essere ancora più veloci di una scansione di raccolta completa). – wp78de

0

questo è il modo mongo lavora con questo tipo di espressioni regolari e un indice. Quello che voglio dire è che stai cercando/bar/invece di/^ bar /.

Quando si specifica un indice su quel campo, si sta indicizzando dal primo carattere. Quindi "Foo barius" viene indicizzato a partire da F. Poiché stai cercando "bar" in qualsiasi punto del campo, devi cercare l'intero indice su quel campo guardando * bar *.

La prima riga del tuo commento dice che guardi ogni record dell'indice.

La seconda riga dice, dammi solo quegli indici da (1) che hanno barra in loro.

Bottom line: progetta i tuoi record in modo che utilizzino l'indice in modo efficiente. Nel caso delle stringhe, assicurati che le tue ricerche siano all'inizio della stringa, ad esempio// bar /. Se sto andando a cercare per cognome allora deve prima apparire in un campo indicizzato.

Come esercizio fare una spiegazione su/^ barra/invece. Non otterrai i tuoi dati, ma i primi limiti dell'indice saranno qualcosa come/^ bar/per/^ bas /.

Spero che la mia risposta al flusso di coscienza sia utile.

UDude

-1

Ho pensato di aggiungere i miei due centesimi.

Le due risposte precedenti sono corrette. L'espressione regolare è in grado di utilizzare un indice standard solo se si avvia la ricerca dall'inizio. In realtà, avere un indice e una ricerca per regex può avere un effetto negativo sulla tua ricerca perché tenta di usare l'indice ma non avrà successo.

C'è un altro tipo di indice che può essere utile nella vostra situazione. Indice di testo di Mongo.Indicizza ogni parola in base a spazi, quindi sarebbe in grado di fare una ricerca indicizzata su entrambe le parole "foo" e "Barius", che potrebbe essere più utilizzare

Ecco la documentazione per che: https://docs.mongodb.com/manual/core/index-text/