Comprendere il DSL di Elasticsearch

Non solo copiare da Stack Overflow ma capire cosa stai copiando.

Elasticsearch è il motore di ricerca per eccellenza in questi giorni, ma il suo DSL di query ha una ripida curva di apprendimento. Quando ho iniziato a scrivere query Elasticsearch, potevo mettere insieme qualcosa che funzionava attraverso una combinazione di documenti di Elastic.co e Stack Overflow, ma non capivo appieno i concetti sottostanti la sintassi.

Questo tutorial vuole essere quello che avrei voluto leggere per primo. Presuppone che il lettore abbia familiarità con i concetti di base di Elasticsearch, possa scrivere semplici query e comprenda la logica booleana. Ha lo scopo di fornire al lettore una solida base concettuale di Elasticsearch prima di provare a capire la sintassi.

Filtrare i valori esatti vs. ricerca analizzata a tutto testo

Un tema dominante in Elasticsearch è che tutte le query possono essere classificate in tre tipi:

1. Filtraggio per valori esatti
2. Ricerca su testo analizzato
3. Una combinazione dei due

Ogni campo del documento può essere classificato come valore esatto o testo analizzato (chiamato anche full text). I valori esatti sono campi come user_iddateemail_addresses, ecc. Il testo analizzato è dati di testo come product_description o email_body. Come il nome implica, questi dati di testo sono stati analizzati (ne parleremo più avanti). È spesso in un linguaggio naturale umano, ma non necessariamente.

L’interrogazione dei documenti può essere fatta specificando i filtri sui valori esatti. In questi casi, la domanda se il documento viene restituito è un sì o un no binario. Per esempio, il user_id del documento è uguale a 174517 ? La data created_at del documento è compresa nell’intervallo dell’ultimo mese?

D’altra parte, l’interrogazione dei documenti attraverso la ricerca del testo analizzato restituisce risultati basati sulla rilevanza. Un documento non è restituito da un criterio sì/no, ma da quanto è rilevante. Per esempio, se il testo analizzato di un documento include Johnny Depp, dovrebbe essere restituito anche nelle ricerche di John Depp o Johnnie Depp. Una ricerca per cook dovrebbe anche restituire risultati per cooking e cooked.

Da questo comportamento, possiamo dedurre che la ricerca per testo analizzato è un’operazione molto complessa e coinvolge diversi pacchetti di analizzatori a seconda del tipo di dati testuali. Per esempio, alcuni pacchetti di analizzatori sono specifici per la lingua e vengono utilizzati per analizzare il testo in una certa lingua. Il pacchetto analizzatore predefinito è l’analizzatore standard che divide il testo in base ai confini delle parole, alle lettere minuscole e rimuove la punteggiatura. Poiché la ricerca per testo analizzato è molto più complicata del filtraggio per valori esatti, è molto meno performante del semplice filtraggio per valori esatti. Nota, chiameremo la ricerca per testo analizzato come ricerca analizzata per brevità.

Il DSL delle query

Le query di Elasticsearch sono composte da una o molte clausole di query. Le clausole di query possono essere combinate per creare altre clausole di query, chiamate clausole di query composte. Tutte le clausole di query hanno uno di questi due formati:

{
QUERY_CLAUSE: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}{
QUERY_CLAUSE: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}

La regola della sintassi è che le clausole di query possono essere ripetutamente annidate dentro altre clausole di query

{
QUERY_CLAUSE {
QUERY_CLAUSE: {
QUERY_CLAUSE: {
QUERY_CLAUSE: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
}
}

Queste sono alcune clausole di query comuni.

Clausola di query match

La clausola di query match è la più generica e comunemente usata. È abbastanza intelligente in quanto quando viene eseguita su un campo di testo analizzato, esegue una ricerca analizzata sul testo. Quando viene eseguita su un campo di valore esatto, esegue un filtro.

Nell’esempio qui sotto, la prima clausola di query eseguirà una ricerca analizzata poiché description è un campo di testo analizzato. Mentre le seconde 2 query sono filtri su campi di valore esatto.

{ "match": { "description": "Fourier analysis signals processing" }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "visible": true }}

La clausola match all query

La clausola match all query restituisce tutti i documenti. È analoga a SELECT * FROM table in SQL.

{ "match_all": {} }

La clausola di query Term/Terms

Le clausole di query term e terms sono usate per filtrare un campo a valore esatto per valori singoli o multipli, rispettivamente. Nel caso di valori multipli, la connessione logica è OR .

Per esempio, la prima query trova tutti i documenti con il tag “math”. La seconda query trova tutti i documenti con i tag “math” o “statistics”.

{ "term": { "tag": "math" }}
{ "terms": { "tag": }}

Clausola di query multi match

La clausola di query multi match è una query che viene eseguita su più campi invece che su uno solo.

{
"multi_match": {
"query": "probability theory",
"fields":
}
}

Clausola di query con filtri Exists e Missing

Il filtro exists controlla che i documenti abbiano un valore in un campo specificato. Il filtro mancante controlla che i documenti non abbiano un valore in un campo specificato. Sono analoghi alle clausole IS NULL e IS NOT NULL di SQL.

{
"exists" : {
"field" : "title"
}
}

e

{
"missing" : {
"field" : "title"
}
}

Clausola di query filtro range

La clausola di query filtro range è usata per filtrare i campi numero e data in range, utilizzando gli operatori gtgteltlte breve per greater_thangreater_than_or_equalless_than e less_than_or_equal , rispettivamente.

{ "range" : { "age" : { "gt" : 30 } } }{ 
"range": {
"born" : {
"gte": "01/01/2012",
"lte": "2013",
"format": "dd/MM/yyyy||yyyy"
}
}
}

Clausola di query composta

Le clausole di query che sono costruite da altre clausole di query sono chiamate clausole di query composte. Si noti che le clausole di query composte possono anche essere formate da altre clausole di query composte, permettendo una nidificazione a più livelli.

La clausola di query bool è un esempio di clausola di query composta, poiché è usata per combinare più clausole di query usando operatori booleani. I tre operatori booleani supportati sono mustmust_not e should , che corrispondono rispettivamente a ANDNOT , e OR .

Per esempio, supponiamo di avere un indice sul posts di un popolare sito di social media. Ecco una query per trovare tutti i posts sulla matematica che non è probabilità, dove è o non letto o è stato favorito.

{
"bool": {
"must": { "term": { "tag": "math" }},
"must_not": { "term": { "tag": "probability" }},
"should":
}
}

Combinare la ricerca analizzata con i filtri

Abbiamo parlato di filtri per campi esatti e ricerca analizzata in contesti separati, ma nelle applicazioni del mondo reale, spesso vogliamo combinare i due. Combiniamo la ricerca analizzata e i filtri di campo esatti usando la clausola filtered.

Per esempio, supponiamo di avere un indice sul posts di un popolare forum web sulla matematica. Ecco una query per trovare tutti i post eseguendo una ricerca analizzata per “Teoria della probabilità”, ma vogliamo solo i posts con 20 o più voti e non quelli con il tag “frequentista”.

{
"filtered": {
"query": { "match": { "body": "Probability Theory" }},
"filter": {
"bool": {
"must": {
"range": { "upvotes" : { "gt" : 20 } }
},
"must_not": { "term": { "tag": "frequentist" } }
}
}
}
}

Summary

Lo sfondo concettuale del DSL di query Elasticsearch è questa dicotomia tra filtrare i documenti e cercare nel testo analizzato. Spero che abbiate trovato questo utile.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *