Questa guida è un po 'fuorviante. È più complicato ed è molto difficile provare a scrivere una serie di regole che si adattino a tutte le situazioni. Quando i dati cambiano, le regole cambiano. Man mano che cambiano i tipi di query e di filtro, le regole cambiano. Un filtro specifico potrebbe essere più lento da eseguire rispetto a uno ampio, le regole cambiano. Su una base per segmento, la dimensione del risultato di un filtro potrebbe essere opposta rispetto a quella di un altro segmento, non è sempre prevedibile. Quindi, per prima cosa devi capire più dettagli interni, quindi devi lasciar andare cercando di controllarlo mentre ti muovi nella moderna Elasticsearch 2.x.
NOTA:vostra seconda citazione (ordine del filtro) e collegamento associato è quello di una pagina che è considerato "fuori data" per elasticsearch 2.x, sarà aggiornato in seguito. Pertanto il consiglio può o non può applicarsi ai tempi moderni.
Guardando indietro nel tempo per elasticsearch 1.x e il motivo per il suggerimento ordinazione:
Parliamo prima di come i filtri sono rappresentati in memoria. Si tratta di una lista iterata di documenti corrispondenti o di un modello di "accesso casuale". A seconda del tipo di filtro, dipende da quale è più efficiente.Ora se tutto è memorizzato nella cache, li stai solo intersecando e il costo varierà in base alla dimensione e al tipo.
Se i filtri non vengono memorizzate, ma sono cacheable poi un filtro eseguirà indipendentemente ed i filtri precedenti influenzerà solo dal costo complessivo di intersezione.
Se il filtro non è cacheable allora potrebbe essere guidata dai risultati precedenti. Immagina uno Query
più uno Filter
. Se esegui la query e dopo aver applicato il filtro, stai facendo molto lavoro extra se il filtro limita a un set molto piccolo di record. Hai perso tempo nella query con la raccolta, il punteggio e la creazione di una serie di risultati complessivi. Ma se si converte a un FilteredQuery
e fare entrambe le cose allo stesso tempo, allora la Query
ignora tutti i record già eliminati dal Filter
. Basta considerare gli stessi documenti già in gioco. Questo è chiamato "saltare". Non tutti i tipi di filtro sfruttano il salto, ma alcuni possono. Ed è per questo che un filtro "guida" più piccolo farà sì che gli altri lo usino più velocemente.
A meno che non si conosca ciascun tipo di filtro, l'euristica dei dati e in che modo ciascun filtro specifico sarà interessato da ciascuno di questi, non si dispone di informazioni sufficienti per dire solo "inserire prima la maggior parte dei filtri limitati e quelli più grandi second " e spero che funzioni. Per bool
l'impostazione predefinita non è memorizzare nella cache il risultato complessivo in modo da prestare attenzione alle sue prestazioni ripetute (e/o memorizzarlo nella cache). È più efficiente quando un lato dell'intersezione del filtro è piccolo. Quindi, avere un piccolo inizio, rende più veloci tutte le altre intersezioni perché possono ridursi. Se si trattasse di una query bool
invece di un filtro di facendo segnare è ancora più importante per evitare segnando più documenti del necessario.
Un'altra nota importante è che "filtro più specifico prima" a volte può essere lenta (filtro di script, o altro), in modo che in realtà dovrebbe leggere: "più basso costo, filtri più specifici primi".
Con Elasticsearch 2.0, things will change:
È il momento di dimenticare tutto ciò che sapeva sulle query e filtri: elasticsearch 2.0 prendere decisioni molto meglio da sola, invece di affidarsi agli utenti di formulare una query ottimizzata.
In 2.x dovresti provare meno a giocare al sistema e lasciare che il motore faccia le scelte migliori. In realtà il motore potrebbe finire con qualcosa di molto diverso sotto il cofano, un filtro riscritto, un cambiamento completo nella struttura interna e nei dati. E potresti anche non controllare più il caching. Quindi devi leggere di più a riguardo.
Il precedente API di filtro potrebbe essere consumati in due modi: o utilizzando iteratori i documenti corrispondenti, oppure utilizzando un'API ad accesso casuale opzionale che ha permesso di verificare se un particolare documento abbinato al filtro oppure no. Tutto è bene finora, salvo che il modo migliore per consumare un filtro dipendeva quale tipo di filtro si ha: per esempio il filtro script
era più efficiente quando si utilizza l'API di accesso casuale mentre il filtro bool
era più efficiente utilizzando l'API iteratore . Questo era piuttosto un incubo per ottimizzare e fu la causa principale per cui il filtro bool
da un lato e le and
e or
filtri dall'altro Dinamiche diverse.
Il motore ora deciderà cosa è meglio prendere in considerazione più fattori tra cui il punteggio, la stima della dimensione del risultato, il modo migliore per intersecare i filtri correlati, magari anche su base per segmento, e altro ancora.
Anche questo articolo chiarisce che anche il caching può essere fuorviante, non sempre rende le cose più veloci. A volte una struttura di dati interna è migliore quando originariamente utilizzata, rispetto alla struttura bitset che viene sempre memorizzata nella cache. Così anche in 2.x questo sta cambiando per evitare di memorizzare nella cache cose che si eseguono meglio dalla struttura di dati nativi senza memorizzare nella cache.
Nel post del blog Roaring Bitmaps sono ulteriori dettagli:
Chiaramente il requisito più importante è avere qualcosa di veloce: se il filtro nella cache è più lento di esecuzione nuovamente il filtro, non è solo consumando memoria, ma anche rendendo le tue domande più lente. Il più sofisticato una codifica è, il più probabile è quello di rallentare la codifica e la decodifica a causa del maggiore utilizzo della CPU
Qui si ottiene un sacco di informazioni circa le strutture dati interne, caching, intersezione e più sulla modifiche interne in 2.x che ti aiuteranno ad avere una maggiore comprensione delle prestazioni del filtro.
Anche se può sorprendere se siete nuovi per la ricerca interni del motore, uno dei più importanti elementi costitutivi di un motore di ricerca è la capacità di comprimere in modo efficiente e decodificare liste ordinate di interi in fretta.
Da questi ultimi due link di blog 2.x hai un sacco di informazioni sulla tua domanda, parlano di tutti i problemi che stai cercando di aggirare con l'ordinamento dei filtri. Le informazioni e i dettagli sono tutti lì e puoi avere una migliore comprensione di 1.x contro 2.x e di come le query + i filtri sono risolti. Quindi ricorda:
Non esiste un'implementazione particolare che sia costantemente migliore di tutte le altre.
Vedi anche queste risorse 1.x di riferimento storico:
Optimizing Elasticsearch searches copre un po 'di più su ordinazione del filtro. In sintesi:
Detto questo, è ancora necessario pensare a quale ordine si filtra. Si desidera che i filtri più selettivi vengano eseguiti per primi. Supponi di filtrare sul tipo: libro e tag: elasticsearch. Se hai 30 milioni di documenti, 10 milioni di libri di testo e solo 10 taggati Elasticsearch, ti consigliamo di applicare prima il filtro dei tag. Riduce il numero di documenti molto più del filtro del libro.
All About Elasticsearch Filter Bitsets è considerato un articolo obsoleto per i tempi moderni, ma dà più di fondo sul documento filtro di ordine che hai citato.
A forum answer by Martijn v Groningen sembra dire il contrario di bool
rispetto a and
query su cui viene utilizzata l'iterazione vs.accesso casuale, ma l'idea è la stessa per ciascuno: sii sicuro limitando i documenti in precedenza nell'elenco dei filtri, indipendentemente dal modello utilizzato per un tipo rispetto all'altro.
Jayson, grazie per il tempo dedicato a questa risposta – Ronald