Prendi in considerazione l'utilizzo di un indice di testo
con un $text
cerca
. Potrebbe essere una soluzione di gran lunga migliore rispetto all'utilizzo di espressioni regolari. Tuttavia, la ricerca di testo restituisce i documenti in base a un algoritmo di punteggio, quindi potresti ottenere alcuni risultati che non hanno tutte le parole chiave che stai cercando.
Se non puoi o non vuoi aggiungere un indice di testo a questo campo, usare una singola espressione regolare sarebbe piuttosto doloroso perché non conosci l'ordine in cui appaiono queste parole. Non pretendo che sia impossibile scrivere, ma finirai con un orribile abominio anche per gli standard regex. Sarebbe molto più semplice utilizzare l'operatore regex più volte utilizzando $and
operatore.
Inoltre, l'utilizzo di uno spazio come delimitatore fallirà quando la parola si trova all'inizio o alla fine della stringa o è seguita da un punto o da una virgola. Usa il token di confine della parola (\b
) invece.
collection.find(
{ $and : [
{'documenttextfield': {'$regex': '\b' +keyword1+'\b'}},
{'documenttextfield': {'$regex': '\b' +keyword2+'\b'}},
{'documenttextfield': {'$regex': '\b' +keyword3+'\b'}},
]
});
Tieni presente che questa è una query molto lenta, perché eseguirà queste tre espressioni regolari su ogni singolo documento della raccolta. Quando questa è una query critica per le prestazioni, considera seriamente se un indice di testo non funzionerà davvero. In caso contrario, l'ultima goccia da cogliere sarebbe estrarre qualsiasi parola chiave dal documenttextfield
campo che qualcuno potrebbe cercare (che potrebbe essere ogni parola univoca in esso contenuta) in un nuovo campo array documenttextfield_keywords
, crea un indice normale su quel campo e cerca in quel campo con $all
operatore
(in questo caso non è richiesta alcuna espressione regolare).