Sto provando a utilizzare MongoDB per implementare un dizionario di lingua naturale. Ho una collezione di lessemi, ognuno dei quali ha un numero di wordforms come documenti secondari. Questo è ciò che un singolo lessema assomiglia:Accelerare la ricerca di stringhe regolari in MongoDB
{
"_id" : ObjectId("51ecff7ee36f2317c9000000"),
"pos" : "N",
"lemma" : "skrun",
"gloss" : "screw",
"wordforms" : [
{
"number" : "sg",
"surface_form" : "skrun",
"phonetic" : "ˈskruːn",
"gender" : "m"
},
{
"number" : "pl",
"surface_form" : "skrejjen",
"phonetic" : "'skrɛjjɛn",
"pattern" : "CCCVCCVC"
}
],
"source" : "Mayer2013"
}
Attualmente ho una collezione di circa 4000 lessemi, e ciascuno di questi ha, in media, una lista di alcuni 1000 wordforms (piuttosto che semplicemente 2 di cui sopra). Ciò significa che ho affettivamente 4.000.000 forme di parole uniche nella raccolta e devo essere in grado di cercare attraverso di loro in un ragionevole lasso di tempo.
Una query normale sarebbe simile a questa:
db.lexemes.find({"wordforms.surface_form":"skrejjen"})
Ho un indice su wordforms.surface_form
, e questa ricerca è molto veloce. Tuttavia, se desidero avere caratteri jolly nella mia ricerca, la performance è abissale. Ad esempio:
db.lexemes.find({"wordforms.surface_form":/skrej/})
richiede più di 5 minuti (a quel punto ho rinunciato ad aspettare). Come accennato a in this question, la ricerca di espressioni regolari sugli indici è nota per essere negativa. So che aggiungendo il^anchor in regex cerca helps a lot, ma limita anche severamente le mie capacità di ricerca. Anche se sono disposto a fare questo sacrificio, ho notato che i tempi di risposta possono variare molto a seconda della regex. La query
db.lexemes.find({"wordforms.surface_form":/^s/})
Takes 35s per completare.
I migliori risultati che ho avuto finora sono stati quando ho spento l'indice usando hint
. In questo caso, le cose sembrano migliorare notevolmente. Questa query:
db.lexemes.find({"wordforms.surface_form":/skrej/}).hint('_id_')
richiede circa 3 secondi per completare.
La mia domanda è, c'è qualcos'altro che posso fare per migliorare questi tempi di ricerca? Così come sono, sono ancora un po 'lenti e sto già pensando di migrare a MySQL nella speranza di ottenere prestazioni. Ma mi piacerebbe davvero mantenere la flessibilità di Mongo ed evitare la noiosa normalizzazione in un RDBMS. Eventuali suggerimenti? Pensi che mi imbatterò in qualche lentezza indipendentemente dal motore DB, con questa quantità di dati testuali?
Conosco la nuova funzionalità di text search di Mongo, ma i vantaggi di questo (tokenizzazione e derivazione) non sono rilevanti nel mio caso (per non dire che la mia lingua non è supportata). Non è chiaro se la ricerca di testo è in realtà più veloce rispetto all'utilizzo di espressioni regolari comunque.
Grazie per il suggerimento! Questo, naturalmente, introduce un sacco di informazioni ridondanti e farà la raccolta complessiva più ampia, se aumenta il tempo di risposta di ricerca allora potrei prendere in considerazione. Farò alcuni test per vedere se questo è il caso e pubblicare un aggiornamento qui. –