Sto tentando di utilizzare un indice di copertura per implementare la ricerca del testo di derivazione sulla mia app che utilizza mongodb.Impossibile ottenere una query coperta per utilizzare l'indice solo in mongodb
Ho il seguente set di indice:
ensureIndex({st: 1, n: 1, _id: 1});
Ma quando ho eseguito spiegare() sulla mia domanda, non riesco mai a ottenere l'indexonly leggere vero, non importa quello che faccio.
db.merchants.find({st: "Blue"}, {n:1,_id:1}).explain()
{
"cursor" : "BtreeCursor st_1_n_1__id_1",
"nscanned" : 8,
"nscannedObjects" : 8,
"n" : 8,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"st" : [
[
"Blue",
"Blue"
]
],
"n" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
Ho già capito che l'ordinamento delle chiavi nell'indice importa in qualche modo. Per esempio se ho usato {_id, n: 1, st: 1} non stava usando questo indice affatto per eseguire la query. Ho anche letto da qualche parte che troppo pochi documenti potrebbero innescare comportamenti imprevedibili con explain() poiché più strategie sono ugualmente veloci. Ma in questo caso, vedo che sta usando l'indice giusto, ma non sta usando solo l'indice. Cosa sta succedendo?
Sto usando mongoid e mongo 2.0.8 Credo.
UPDATE:
passa ad utilizzare Mongoid v3.1.4 e v2.2 mongod
Ecco la query che mongod sta vedendo da mongoid: Lun 15 Lug 10:47:26 [conn14] RunQuery chiamato spl_development.merchants {$ query: {st: {$ regex: "cr", $ opzioni: "i"}}, $ explain: true} lun 15 lug 10:47:26 [conn14] query spl_development.merchants query: {$ query: {st: {$ regex: "cr", $ opzioni: "i"}}, $ spiega: true} ntoreturn: 0 keyUpdates: 0 lock (micros) r: 212 nreturned: 1 reslen: 393 0ms
Quindi la proiezione non viene inviata al mongod strato e lo gestisce solo nel livello dell'applicazione. Non è l'ideale!
Ciò è stato riconosciuto come un bug in mongoid e possono essere monitorati qui: https://github.com/mongoid/mongoid/issues/3142
Grazie Stennie, questo è esattamente giusto, 'st' è una matrice. Immagino che per implementare questo e garantire che sia una query coperta per la velocità, devo usare regex sul campo di testo, mentre la mia strategia precedente era che avevo diviso il testo in parole in una matrice. Speriamo che la lentezza della regex sarà compensata dal fatto che il risultato viene restituito dall'indice di memoria. –
È possibile utilizzare le espressioni regolari per rendere questa una query coperta, ma per un indice efficiente utilizzare la regex dovrebbe essere root-root (ad esempio '/^Blue /') e maiuscole e minuscole. Controlla il valore 'nscanned' quando aggiungi la tua espressione regolare per vedere il numero di confronti dell'indice richiesti rispetto a' n' (il numero di risultati restituiti). È inoltre possibile rendere una query coperta separando gli array di parole chiave in più documenti con un singolo campo indicizzato. Vorrei confrontare i diversi approcci per vedere cosa funziona meglio per il tuo caso d'uso; un multitasto (ma un indice non coperto) può effettivamente andare bene :) – Stennie
Si noti inoltre che è stata elaborata una funzionalità di ricerca del testo migliorata (arginamento, punteggio, corrispondenza frase, parole di arresto, ..) per MongoDB 2.4 (vedere [SERVER- 380] (https://jira.mongodb.org/browse/SERVER-380)). Dovresti essere in grado di testarlo nella prossima versione di sviluppo 2.3.2 (o build notturne se sei impaziente/curioso). Post di blog di qualcuno che sta provando a farlo: [Spiegazione di testo di MongoDB] (http://blog.codecentric.de/en/2013/01/text-search-mongodb-stemming/). – Stennie