Padroneggiare Elasticsearch Una guida per principianti alle ricerche potenti e precise – Parte 1

Il dominio di Elasticsearch Una guida per principianti alla ricerca potente e precisa - Parte 1

Contenuti

· Introduzione· Riprendendo da dove ci siamo fermati, Elasticsearch ∘ Dataset di esempioComprensione delle query di ElasticSearchComprensione della rispostaUna query di ricerca di base· Ricerca lessicale· Problemi nella nostra query di ricerca attualeParole simili restituiscono risultati differentiMancanza di comprensione di ciò che l’utente vuoleParole simili non vengono restituiteGli errori di battitura vengono ignoratiDiverse combinazioni di parole hanno significati diversi· Migliorare la nostra ricercaPotenziare campi più rilevantiPotenziamento basato su funzioniQuery fuzzy· Conclusione

Introduzione

Vi siete mai chiesti come trovate senza sforzo il paio di scarpe perfetto online o incappiate in un post di un amico nel vasto mondo dei social media? Tutto grazie all’eroe senza nome delle esperienze digitali: i sistemi di ricerca.

Ripensate al vostro ultimo acquisto online – che si tratti di un elegante paio di scarpe o di un libro pensato per un amico. Come avete trovato esattamente ciò che stavate cercando? Probabilmente avete navigato attraverso un mare di opzioni utilizzando la barra di ricerca! Questa è la magia dei sistemi di ricerca, che plasmano silenziosamente le nostre esperienze online e rendono facilissimo scoprire la scelta perfetta tra gli scaffali digitali. In un mondo ricco di scelte, la capacità di trovare ciò che cerchiamo in modo rapido e senza sforzo è una testimonianza dell’importanza di sistemi di ricerca robusti e intuitivi per i prodotti che amiamo.

Nella mia recente esplorazione di Elasticsearch (date un’occhiata alla mia introduzione sulla sua architettura e terminologia), abbiamo scoperto il motore che alimenta queste scoperte. Questo post si addentra nella ricerca – nell’attraversare le query di ElasticSearch, nel comprendere le risposte e nella creazione di una query di base per preparare il terreno.

Il nostro obiettivo: costruire una semplice query di ricerca, individuare i problemi e migliorarla con esempi pratici. Unitevi a noi nel riconoscere le sfide all’interno del nostro attuale sistema di ricerca e nel scoprire il percorso verso il perfezionamento in questo mondo di scaffali digitali.”

Partendo da dove abbiamo lasciato, Elasticsearch

Dataset di anteprima

Per dimostrare diversi modi in cui possiamo migliorare la ricerca, impostiamo Elasticsearch e carichiamo alcuni dati in esso. Per questo post, utilizzerò questo dataset di notizie che ho trovato su Kaggle. Il dataset è abbastanza semplice, contiene circa 210.000 articoli di notizie, con titoli, brevi descrizioni, autori e alcuni altri campi a cui non diamo molta importanza. Non abbiamo davvero bisogno di tutti i 210.000 documenti, quindi caricherò circa 10.000 documenti in ES e inizierò a cercare.

Ecco alcuni esempi dei documenti nel dataset —

[  {    "link": "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",    "headline": "Perché la Board delle Elezioni di New York è un disastro",    "short_description": "“C'è un problema fondamentale nel avere consigli elettorali partigiani,” ha detto un avvocato elettorale di New York.",    "category": "POLITICA",    "authors": "Daniel Marans",    "country": "IN",    "timestamp": 1689878099  },  ....]

Ogni documento rappresenta un articolo di notizie. Ogni articolo contiene un link, un headline, una short_description, una category, authors, country (valori casuali, aggiunti da me) e timestamp (di nuovo valori casuali, aggiunti da me).

Ho aggiunto i campi country e timestamp per rendere più divertenti gli esempi nelle sezioni successive, quindi cominciamo!

Comprensione delle Query di ElasticSearch

Le query di Elasticsearch sono scritte in JSON. Invece di approfondire tutte le diverse sintassi che puoi usare per creare query di ricerca, cominciamo in modo semplice e costruiamo da lì.

La query di testo completo più semplice è la query match. L’idea è semplice, scrivi una query ed Elasticsearch esegue una ricerca di testo completo su un campo specifico. Ad esempio,

GET news/_search{  "query": {    "match": {      "headline": "rapina"    }  }}

La query precedente trova tutti gli articoli in cui la parola “rapina” appare nel “headline”. Questi sono i risultati che ho ottenuto –

{  "_index" : "news",  "_id" : "RzrouIsBC1dvdsZHf2cP",  "_score" : 7.4066687,  "_source" : {    "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",    "headline" : "Bandit The 'Guard Cat' Hailed As Hero After Thwarting Would-Be Robbery",    "short_description" : "Quando almeno due persone hanno cercato di entrare in una casa a Tupelo, Mississippi, la scatola ha fatto tutto il possibile per avvertire il proprietario.",    "category" : "NEWS STRANA",    "authors" : "",    "country" : "US",    "timestamp" : 1693070640  }},{  "_index" : "news",  "_id" : "WTrouIsBC1dvdsZHp2wd",  "_score" : 7.4066687,  "_source" : {    "link" : "https://www.huffpost.com/entry/san-francisco-news-crew-security-guard-shot-killed_n_61a2a9d8e4b0ae9a42af278a",    "headline" : "Guardia di sicurezza di una troupe di notizie muore dopo essere stato colpito mentre aiutava la copertura di una rapina",    "short_description" : "Kevin Nishita è stato colpito all'addome mentre faceva il suo lavoro in mezzo a un aumento del crimine organizzato nel commercio al dettaglio.",    "category" : "CRIMINALITÀ",    "authors" : "Daisy Nguyen, AP",    "country" : "US",    "timestamp" : 1692480894  }}

Ma, cosa succederebbe se volessi effettuare una ricerca di testo completo su più campi? Puoi farlo con una query multi_match,

GET news/_search{  "query": {    "multi_match": {      "query": "rapina",      "fields": ["titolo", "descrizione_breve"]    }  }}

Questa operazione esegue una ricerca simile, ma anziché cercare in un singolo campo, guarda sia il campo titolo che il campo descrizione_breve di tutti i documenti e effettua una ricerca full-text su di essi.

Comprensione della risposta

Questa è una risposta di esempio dalla nostra ultima ricerca:

{  "took" : 5,  "timed_out" : false,  "_shards" : {    "total" : 1,    "successful" : 1,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : {      "value" : 2,      "relation" : "eq"    },    "max_score" : 29.626675,    "hits" : [      {        "_index" : "news",        "_id" : "RzrouIsBC1dvdsZHf2cP",        "_score" : 29.626675,        "_source" : {          "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",          "headline" : "Il gatto 'Guardia' Bandit osannato come eroe dopo aver sventato una rapina",          "short_description" : "Quando almeno due persone hanno cercato di entrare in una casa a Tupelo, Mississippi, la scat ha fatto tutto il possibile per avvertire il proprietario.",          "category" : "NOTIZIE STRANE",          "authors" : "",          "country" : "US",          "timestamp" : 1693070640        }      },      .....    ]  }}

I campi took e timed_out sono abbastanza facili da capire, rappresentano semplicemente il tempo in millisecondi impiegato da Elasticsearch per restituire la risposta e se la query è scaduta o meno.

Il campo _shards indica quanti shard sono coinvolti in questa operazione di ricerca, quanti di essi sono riusciti, quanti sono falliti e quanti sono stati ignorati.

Il campo hits contiene i documenti restituiti dalla ricerca. Ad ogni documento viene assegnato un punteggio in base alla sua rilevanza per la ricerca. Il campo hits contiene anche un campo total che indica il numero totale di documenti restituiti e il punteggio massimo dei documenti.

Infine, nel campo annidato hits, otteniamo tutti i documenti rilevanti, insieme al loro _id e al loro score. I documenti sono ordinati in base al loro punteggio.

Una query di ricerca di base

Iniziamo a costruire la nostra query di ricerca. Possiamo iniziare con una query semplice e analizzarne i problemi:

GET news/_search{  "query": {    "multi_match": {      "query": "rapina",      "fields": ["titolo", "descrizione_breve"]    }  }}

Questa è una query piuttosto semplice, semplicemente trova tutti i documenti in cui appare la parola “rapina” in uno dei campi specificati, ovvero titolo o descrizione_breve.

Restituisce alcuni risultati e possiamo vedere che tutti hanno la parola “rapina” al loro interno.

{  .....  "hits" : {    "total" : {      "value" : 3,      "relation" : "eq"    },    "max_score" : 8.164355,    "hits" : [      {        "_index" : "news",        "_id" : "hjrouIsBC1dvdsZHgWdm",        "_score" : 8.164355,        "_source" : {          "link" : "https://www.huffpost.com/entry/lady-gaga-dog-walker-reward_n_62d82efee4b000da23fafad7",          "headline" : "Ricompensa di $5.000 per il sospettato di aver sparato al dog walker di Lady Gaga",          "short_description" : "Uno degli uomini coinvolti nella rapina violenta era stato erroneamente rilasciato dalla custodia nell'aprile e resta disperso.",          "category" : "NOTIZIE STATUNITENSI",          "authors" : "STEFANIE DAZIO, AP",          "country" : "IN",          "timestamp" : 1694863246        }      },      {        "_index" : "news",        "_id" : "RzrouIsBC1dvdsZHf2cP",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",          "headline" : "Il gatto 'Guardia' Bandit osannato come eroe dopo aver sventato una rapina",          "short_description" : "Quando almeno due persone hanno cercato di entrare in una casa a Tupelo, Mississippi, la scat ha fatto tutto il possibile per avvertire il proprietario.",          "category" : "NOTIZIE STRANE",          "authors" : "",          "country" : "US",          "timestamp" : 1693070640        }      },      {        "_index" : "news",        "_id" : "WTrouIsBC1dvdsZHp2wd",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/san-francisco-news-crew-security-guard-shot-killed_n_61a2a9d8e4b0ae9a42af278a",          "headline" : "La guardia di sicurezza del team di notizie muore dopo essere stato colpito mentre copriva la rapina",          "short_description" : "Kevin Nishita è stato colpito all'addome mentre faceva il suo lavoro in mezzo ad un aumento della criminalità organizzata nel settore del commercio al dettaglio.",          "category" : "CRIMINALITÀ",          "authors" : "Daisy Nguyen, AP",          "country" : "US",          "timestamp" : 1692480894        }      }    ]  }}

Ciò a cui ci siamo fino ad ora dedicati è chiamato ‘ricerca lessicale’. In questo tipo di ricerca, il sistema cerca corrispondenze precise per una determinata parola o frase all’interno dei documenti. In sostanza, quando un utente inserisce ‘rapina’, la nostra query di ricerca identifica tutti i documenti che contengono il termine esatto ‘rapina’. Sebbene questo metodo possa sembrare intuitivo inizialmente, le sue limitazioni diventano evidenti abbastanza rapidamente, come scopriremo presto.

Problemi nella nostra query di ricerca attuale

Parole simili restituiscono risultati diversi

Prendiamo alcuni esempi, vediamo cosa otteniamo quando l’utente cerca “derubato” —

GET news/_search{  "query": {    "multi_match": {      "query": "derubato",      "fields": ["titolo", "descrizione_breve"]    }  }}

Ecco i risultati che ottengo —

{    "total" : {      "value" : 2,      "relation" : "eq"    },    "max_score" : 7.9044275,    "hits" : [      {        "_index" : "news",        "_id" : "YTrouIsBC1dvdsZHh2jf",        "_score" : 7.9044275,        "_source" : {          "link" : "https://www.huffpost.com/entry/multiple-guns-robbery-wellston-market-missouri_n_62994cbee4b05fe694f296ad",          "titolo" : "Uomo Derubato Di Fucile D'Assalto A Mano Armata Sparando Con Un'Altra Pistola",          "descrizione_breve" : "Il rapinatore accusato è stato colpito più volte e due passanti sono rimasti feriti nella sparatoria di St. Louis.",          "categoria" : "CRIMINE",          "autori" : "Mary Papenfuss",          "paese" : "IN",          "timestamp" : 1691458552        }      },      {        "_index" : "news",        "_id" : "YDrouIsBC1dvdsZH73UQ",        "_score" : 7.8303137,        "_source" : {          "link" : "https://www.huffpost.com/entry/michigan-militia-training-video-gretchen-whitmer_n_5f8b6e26c5b6dc2d17f78e0a",          "titolo" : "Video Di Addestramento Inquietante Rilasciato Degli Uomini Di Una Milizia Incriminati Nel Complotto Di Rapimento Del Governatore Del Michigan",          "descrizione_breve" : "\"Sono stanco di essere derubato e schiavizzato dallo stato ... loro sono nemici. Punto\", dice un sospetto in un video.",          "categoria" : "POLITICA",          "autori" : "Mary Papenfuss",          "paese" : "IN",          "timestamp" : 1692613291        }      }    ]  }

Per semplificarlo, questi sono i titoli dei documenti che ho ottenuto

1. "Uomo Derubato Di Fucile D'Assalto A Mano Armata Sparando Con Un'Altra Pistola"2. "Video Di Addestramento Inquietante Rilasciato Degli Uomini Di Una Milizia Incriminati Nel Complotto Di Rapimento Del Governatore Del Michigan"

Entrambi questi documenti contengono la parola “derubato” nel titolo o nella descrizione. Ma se l’utente avesse cercato “rapina”, vedremmo un insieme completamente diverso di documenti nei risultati –

[      {        "_index" : "news",        "_id" : "hjrouIsBC1dvdsZHgWdm",        "_score" : 8.164355,        "_source" : {          "link" : "https://www.huffpost.com/entry/lady-gaga-dog-walker-reward_n_62d82efee4b000da23fafad7",          "titolo" : "Ricompensa di $5000 per il Sospetto nel Caso dello Sparo al Passeggiatore del Cane di Lady Gaga",          "descrizione_breve" : "Uno degli uomini coinvolti nella rapina violenta è stato erroneamente rilasciato dalla custodia nell'aprile e rimane disperso.",          "categoria" : "NOTIZIE USA",          "autori" : "STEFANIE DAZIO, AP",          "paese" : "IN",          "timestamp" : 1694863246        }      },      {        "_index" : "news",        "_id" : "YTrouIsBC1dvdsZHh2jf",        "_score" : 8.079888,        "_source" : {          "link" : "https://www.huffpost.com/entry/multiple-guns-robbery-wellston-market-missouri_n_62994cbee4b05fe694f296ad",          "titolo" : "Uomo Derubato Di Fucile D'Assalto A Mano Armata Sparando Con Un'Altra Pistola",          "descrizione_breve" : "Il rapinatore accusato è stato colpito più volte e due passanti sono rimasti feriti nella sparatoria di St. Louis.",          "categoria" : "CRIMINE",          "autori" : "Mary Papenfuss",          "paese" : "IN",          "timestamp" : 1691458552        }      },      {        "_index" : "news",        "_id" : "RzrouIsBC1dvdsZHf2cP",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",          "titolo" : "La Gatta 'Guardia' Salutata Come Eroina Dopo Aver Sventato una Rapina",          "descrizione_breve" : "Quando almeno due persone hanno cercato di entrare in una casa a Tupelo, Mississippi, la gatta ha fatto tutto il possibile per avvertire il proprietario.",          "categoria" : "NOTIZIE STRANE",          "autori" : "",          "paese" : "US",          "timestamp" : 1693070640        }      },      {        "_index" : "news",        "_id" : "WTrouIsBC1dvdsZHp2wd",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/san-francisco-news-crew-security-guard-shot-killed_n_61a2a9d8e4b0ae9a42af278a",          "titolo" : "Guardia di Sicurezza del Team di Notizie Muore Dopo Essere Stata Colpita Mentre Aiutava la Copertura di una Rapina",          "descrizione_breve" : "Kevin Nishita è stato colpito all'addome mentre faceva il suo lavoro in mezzo a un aumento di crimini organizzati nel commercio al dettaglio.",          "categoria" : "CRIMINE",          "autori" : "Daisy Nguyen, AP",          "paese" : "US",          "timestamp" : 1692480894        }      }    ]

1. “Ricompensa di $5000 per il Sospetto nel Caso dello Sparo al Passeggiatore del Cane di Lady Gaga”2. “Uomo Derubato Di Fucile D’Assalto A Mano Armata Sparando Con Un’Altra Pistola”3. “La Gatta ‘Guardia’ Salutata Come Eroina Dopo Aver Sventato una Rapina”4. “Guardia di Sicurezza del Team di Notizie Muore Dopo Essere Stata Colpita Mentre Aiutava la Copertura di una Rapina”

In breve, otteniamo risultati diversi se l’utente cerca “rapina” rispetto a quando cerca “rubato”. Questo ovviamente non è ideale, se l’utente ha cercato uno qualsiasi di questi termini (o qualcosa correlata a “rubare”), dovremmo mostrare tutti i documenti che contengono diverse forme della parola “rubare” (chiamate “forme flesse”) nella query.

Mancanza di comprensione di ciò che l’utente vuole

“L’obiettivo di un designer è ascoltare, osservare, capire, simpatizzare, mettersi nei panni dell’altro, sintetizzare e trarre insegnamenti che gli consentano di rendere visibile l’invisibile.” – Hillman Curtis

Stiamo cercando di recuperare documenti che si allineino con la query dell’utente, un compito che va oltre il solo input dell’utente. Approfondendo ulteriori parametri, otteniamo una comprensione molto più approfondita delle preferenze e dei bisogni del nostro utente.

Ad esempio, quando un utente cerca notizie, il loro interesse probabilmente va oltre la sola rilevanza; la recentezza dell’articolo di notizie è spesso cruciale. Per migliorare la nostra precisione di ricerca, possiamo perfezionare il meccanismo di valutazione.

Inoltre, abbiamo anche un campo location nei nostri articoli. Questo campo indica l’origine geografica delle notizie, offrendo un’opportunità per raffinare ulteriormente i nostri risultati. Possiamo utilizzarlo per aumentare la visualizzazione degli articoli del paese dell’utente.

Parole simili non vengono restituite

Poiché restituiamo solo articoli che contengono l’esatta corrispondenza cercata dall’utente, è probabile che ci stiamo perdendo documenti rilevanti che contengono parole simili. Ad esempio, se cerco “furto”, ottengo gli articoli seguenti:

[      {        "_index" : "news",        "_id" : "dzrouIsBC1dvdsZHiGh1",        "_score" : 8.079888,        "_source" : {          "link" : "https://www.huffpost.com/entry/ap-us-church-theft-beheaded-statue_n_629504abe4b0933e7376f2fa",          "headline" : "Statua di un angelo decapitata in chiesa, rubato un reliquiario da 2 milioni di dollari",          "short_description" : "La chiesa di New York afferma che il suo reliquiario d'oro a 18 carati rubato era protetto dal proprio sistema di sicurezza ed è irrimediabilmente perduto a causa del suo valore storico e artistico.",          "category" : "CRIMINE",          "authors" : "Michael R. Sisak, AP",          "country" : "IN",          "timestamp" : 1699477455        }      },      {        "_index" : "news",        "_id" : "ATrouIsBC1dvdsZHrG2n",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/joseph-sobolewski-charge-dropped-mountain-dew-felony_n_617a15e0e4b0657357447ee2",          "headline" : "L'accusa di reato grave contro l'uomo accusato di furto di una bibita da 43 centesimi è stata ritirata dai pubblici ministeri",          "short_description" : "Joseph Sobolewski rischiava fino a sette anni di prigione dopo aver pagato 2 dollari per una Mountain Dew che costava 2,29 dollari più tasse.",          "category" : "NOTIZIE DEGLI STATI UNITI",          "authors" : "Nick Visser",          "country" : "IN",          "timestamp" : 1698883200        }      },      {        "_index" : "news",        "_id" : "ZDrouIsBC1dvdsZH73Uq",        "_score" : 7.153779,        "_source" : {          "link" : "https://www.huffpost.com/entry/missing-lemur-found_n_5f8b2c33c5b6dc2d17f76bdb",          "headline" : "'C'è un lemure!' Un bambino di 5 anni aiuta a risolvere il caso di furto allo zoo di San Francisco",          "short_description" : """Il lemure di 21 anni affetto da artrosi è "agitato" ma al sicuro, dicono gli addetti allo zoo.""",          "category" : "NOTIZIE DEGLI STATI UNITI",          "authors" : "",          "country" : "IN",          "timestamp" : 1698560597        }      }    ]

La parola “rapina” può avere un significato diverso rispetto alla parola “furto”, ma è comunque una parola rilevante e l’utente potrebbe essere interessato a vedere articoli con la parola “rapina” (anche se con un punteggio di rilevanza inferiore rispetto ai documenti che contengono l’esatta parola cercata dall’utente)

Potrebbero esserci tante parole simili a “furto”, ognuna con diversi livelli di somiglianza. Ad esempio, “furto” potrebbe essere più simile a “furtarello” e meno simile a “scasso”. Ma entrambi possono essere sinonimi tra loro in determinati contesti e avere una certa rilevanza, anche se non tanto rilevanti quanto la parola esatta nella query, cioè “furto”.

La nostra attuale ricerca non tiene conto della somiglianza delle parole nei documenti e nella query. Se un utente cerca “furto”, vengono restituiti solo gli articoli che contengono la parola “furto”, mentre dovremmo restituire anche gli articoli che contengono parole simili a “furto” (come “scasso” o “rapina”).

Gli errori di battitura sono ignorati

“Se l’utente non può usarlo, non funziona.” – Susan Dray

Un altro problema è che qualsiasi errore di battitura da parte di un utente restituirà risultati vuoti. Sappiamo che gli utenti possono commettere errori di battitura per errore, e non vogliamo restituire risultati vuoti. Ad esempio, cercando “robbey” su Google News restituisce comunque risultati correlati a “rapina”.

Diverse combinazioni di parole hanno significati differenti

Guardiamo un esempio, supponiamo che l’utente abbia fatto questa query —

OTTIENI news/_search{  "query": {    "multi_match": {      "query": "nuovo jersey covid virus"    }  }}

Per te e per me, è ovvio che l’utente vuole cercare notizie relative a “covid” o “virus” in “New Jersey”. Ma per il nostro motore di ricerca, ognuna di queste parole significa la stessa cosa, e non ha modo di capire che l’ordine di queste parole conta (ad esempio, “New” e “Jersey” in “New Jersey”).

Guardiamo i primi tre risultati,

{        "_index" : "news",        "_id" : "0jrouIsBC1dvdsZH03FH",        "_score" : 15,199991,        "_source" : {          "link" : "https://www.huffpost.com/entry/covid-new-york-new-jersey-trend_n_60611769c5b6531eed0621da",          "headline" : "La lotta al virus si arena nei primi punti caldi di New York e New Jersey",          "short_description" : "New Jersey ha riportato circa 647 nuovi casi ogni 100.000 residenti negli ultimi 14 giorni. New York ne ha avuti mediamente 548.",          "category" : "NOTIZIE U.S.",          "authors" : "Marina Villeneuve e Mike Catalini, AP",          "country" : "US",          "timestamp" : 1697056489        }      },      {        "_index" : "news",        "_id" : "zzrouIsBC1dvdsZH23Ig",        "_score" : 12,708103,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-variants-raise-worry-about-covid-19-virus-reinfections_n_602193e6c5b689330e31dcc4",          "headline" : "Nuove varianti suscitano preoccupazione riguardo alle reinfezioni da virus COVID-19",          "short_description" : "Gli scienziati hanno scoperto una nuova versione del virus in Sudafrica che è più contagiosa e meno suscettibile a determinati trattamenti.",          "category" : "NOTIZIE MONDIALI",          "authors" : "Marilynn Marchione, AP`",          "country" : "IN",          "timestamp" : 1693063095        }      },      {        "_index" : "news",        "_id" : "fTrouIsBC1dvdsZH6HQF",        "_score" : 11,707885,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-york-covid-19-religious-gatherings_n_5fbf42b8c5b66bb88c6430ac",          "headline" : "Corte Suprema blocca restrizioni COVID-19 a New York per le riunioni religiose",          "short_description" : "È stata la prima grande decisione da quando la giudice Amy Coney Barrett si è unita alla Corte Suprema delle Nazioni Unite.",          "category" : "POLITICA",          "authors" : "Lawrence Hurley, Reuters",          "country" : "IN",          "timestamp" : 1693362371        }      },

Se osservi attentamente i risultati sopra, noterai che il secondo risultato, “Nuove varianti sollevano preoccupazione riguardo alle reinfezioni del virus COVID-19”, è completamente slegato dal New Jersey. Infatti, dopo aver letto la descrizione, sembra essere più correlato alle infezioni da COVID-19 in Sudafrica!

Ciò accade perché le parole “COVID”, “virus” e “Nuove” fanno parte del documento, e quindi il documento ottiene un punteggio più alto. Tuttavia, ciò non è affatto rilevante per la query dell’utente. Il nostro sistema di ricerca non comprende che i termini “Nuove” e “Jersey” dovrebbero essere considerati come un unico termine.

Potenziare campi più rilevanti

“Le parole hanno un peso, quindi se stai per dire qualcosa di importante, assicurati di scegliere le giuste.” – Lang Leav

Possiamo decidere di potenziare determinati campi o determinati valori che potrebbero essere più utili per comprendere di cosa tratta un articolo. Ad esempio, il titolo dell’articolo potrebbe avere un significato maggiore rispetto alla descrizione dell’articolo.

Prendiamo ad esempio una query. Supponiamo che l’utente stia cercando notizie sulle elezioni, ecco come sarebbe la nostra query Elasticsearch —

GET news/_search{  "query": {    "multi_match": {      "query": "elezioni",      "type": "most_fields",       "fields": ["short_description", "headline"]    }  }}

Ecco i risultati che otteniamo-

{        "_index" : "news",        "_id" : "qDrouIsBC1dvdsZHwW-a",        "_score" : 15.736175,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",          "headline" : "Perché il Board delle Elezioni di New York City è un disastro",          "short_description" : "“C'è un problema fondamentale nel fatto che le giunte elettorali siano di parte,” afferma un avvocato delle elezioni di New York.",          "category" : "POLITICA",          "authors" : "Daniel Marans",          "country" : "IN",          "timestamp" : 1689878099        }      },      {        "_index" : "news",        "_id" : "8zrouIsBC1dvdsZH63Si",        "_score" : 7.729385,        "_source" : {          "link" : "https://www.huffpost.com/entry/20-funniest-tweets-from-women-oct-31-nov-6_n_5fa209fac5b686950033b3e7",          "headline" : "I 20 tweet più divertenti delle donne di questa settimana (31 ottobre-6 novembre)",          "short_description" : "\"Ascoltatemi: epidurali, ma per le elezioni.\"",          "category" : "DONNE",          "authors" : "Caroline Bologna",          "country" : "IN",          "timestamp" : 1694723723        }      },      {        "_index" : "news",        "_id" : "zzrouIsBC1dvdsZH8nVe",        "_score" : 7.353842,        "_source" : {          "link" : "https://www.huffpost.com/entry/childrens-books-elections-voting_l_5f728844c5b6f622a0c368a1",          "headline" : "25 libri per bambini che insegnano loro sulle elezioni e sul voto",          "short_description" : "I genitori possono utilizzare queste storie per educare i loro piccoli sul processo politico americano.",          "category" : "GENITORI",          "authors" : "Caroline Bologna",          "country" : "IN",          "timestamp" : 1697290393        }      },

Se guardi il secondo articolo “I 20 tweet più divertenti delle donne di questa settimana (31 ottobre-6 novembre)”, puoi vedere che non sembra affatto parlare di elezioni. Tuttavia, a causa della presenza della parola “elezioni” nella descrizione, Elasticsearch lo considera un risultato rilevante. Forse c’è spazio per miglioramenti. Ha senso intuitivo che gli articoli con titoli che corrispondono alla query dell’utente siano più rilevanti. Per ottenere questo risultato, possiamo istruire Elasticsearch a potenziare il campo titolo, assegnandogli un’importanza maggiore rispetto al campo short_description nei calcoli del punteggio.

È abbastanza semplice da fare nella nostra query-

GET news/_search{  "query": {    "multi_match": {      "query": "elezioni",      "type": "most_fields",       "fields": ["headline^4", "short_description"]    }  }}

Si noti il heading^4 che ho inserito in fields. Questo significa semplicemente che il campo “heading” è potenziato di 4. Ora vediamo i risultati,

{        "_index" : "news",        "_id" : "qDrouIsBC1dvdsZHwW-a",        "_score" : 37.7977,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",          "headline" : "Perché l'Ufficio delle Elezioni di New York City è un Disastro",          "short_description" : "“C'è un problema fondamentale nel avere commissioni elettorali partigiane”, ha detto un avvocato elettorale di New York.",          "category" : "POLITICA",          "authors" : "Daniel Marans",          "country" : "IN",          "timestamp" : 1689878099        }      },      {        "_index" : "news",        "_id" : "zzrouIsBC1dvdsZH8nVe",        "_score" : 29.415367,        "_source" : {          "link" : "https://www.huffpost.com/entry/childrens-books-elections-voting_l_5f728844c5b6f622a0c368a1",          "headline" : "25 Libri per Bambini che Insegnano ai Ragazzi le Elezioni e il Voto",          "short_description" : "I genitori possono utilizzare queste storie per educare i loro piccoli sul processo politico americano.",          "category" : "GENITORI",          "authors" : "Caroline Bologna",          "country" : "IN",          "timestamp" : 1697290393        }      },      {        "_index" : "news",        "_id" : "_jrouIsBC1dvdsZH3HKZ",        "_score" : 29.415367,        "_source" : {          "link" : "https://www.huffpost.com/entry/shirley-weber-first-black-california-secretary-of-state_n_6014651ec5b6aa4bad33e87b",          "headline" : "Shirley Weber Giura come Primo Capo delle Elezioni Nere della California",          "short_description" : "Rinuncia al suo seggio all'Assemblea per diventare il nuovo segretario di stato, sostituendo Alex Padilla, che la settimana scorsa è diventato il primo senatore latino degli Stati Uniti per la California.",          "category" : "POLITICA",          "authors" : "Sarah Ruiz-Grossman",          "country" : "IN",          "timestamp" : 1697300728        }      },      {        "_index" : "news",        "_id" : "NzrouIsBC1dvdsZHnWvd",        "_score" : 26.402336,        "_source" : {          "link" : "https://www.huffpost.com/entry/josh-hawley-democrats-dont-accept-elections_n_61ea1949e4b01440a689bedc",          "headline" : "Sen. Josh Hawley Afferma, Senza Ironia, che i Democratici Non Accettano le Elezioni che Perdono",          "short_description" : "Il repubblicano del Missouri ha guidato l'assedio del 6 gennaio per obiettare alla vittoria di Joe Biden - subito dopo aver salutato i manifestanti pro-Trump che si radunavano al Campidoglio degli Stati Uniti.",          "category" : "POLITICA",          "authors" : "Josephine Harvey",          "country" : "IN",          "timestamp" : 1692046727        }      },

Ora possiamo vedere che tutti i risultati migliori contengono la parola “elezione” nel titolo e quindi gli articoli restituiti sono più rilevanti.

Potenziamento basato su funzioni

Mentre abbiamo potenziato alcuni campi, vogliamo anche introdurre due nuovi tipi di potenziamento basati su ciò che gli utenti desiderano quando cercano notizie.

  1. Vogliamo dare maggiore importanza agli articoli del paese dell’utente. Non vogliamo semplicemente filtrare in base al paese poiché potrebbero apparire risultati non pertinenti in cima, ma non vogliamo nemmeno ignorarlo completamente. In breve, vogliamo dare più peso agli articoli del paese dell’utente.
  2. Vogliamo dare maggiore importanza alle notizie più recenti. Non vogliamo semplicemente ordinare in base alla recente data poiché potrebbero anche apparire risultati non pertinenti in cima, vogliamo invece bilanciare la recentezza con la pertinenza.

Vediamo come fare questo.

In Elasticsearch, possiamo utilizzare la query function_score per applicare funzioni di punteggio personalizzate, compreso il boosting. La query function_score consente di modificare il punteggio dei documenti in base a varie funzioni. In altre parole, possiamo incrementare il punteggio di determinati documenti in base a determinate condizioni.

Iniziamo incrementando il paese dell’utente. Supponiamo che il paese dell’utente sia “US” e inseriamolo nella query quando la inviamo a Elasticsearch. Per ottenere questo, dobbiamo aggiungere un blocco function_score, che consente di applicare funzioni di punteggio personalizzate ai risultati di una query. Possiamo definire più funzioni per una data query, specificando condizioni sul matching del documento e il valore del boosting.

Possiamo definire una funzione per aumentare il punteggio del paese dell’utente —

{  "filter": {    "term": {      "country.keyword": "US"    }  },  "weight": 2}

Questo incrementa il punteggio degli articoli di 2 quando il paese è “US”.

Successivamente, cerchiamo di aumentare le notizie recenti in cima. Possiamo farlo utilizzando field_value_factor. La funzione field_value_factor ci permette di utilizzare un campo di un documento per influenzare il suo punteggio, che è esattamente ciò che vogliamo. Vediamo come si presenta —

{  "field_value_factor": {    "field": "timestamp",    "factor": 2  }}

Il termine factor specifica il moltiplicatore o fattore con cui i valori del campo specificato dovrebbero influenzare il punteggio. Con questa funzione, i documenti con timestamp più recenti riceveranno punteggi più alti.

La nostra query completa diventa —

GET news/_search{  "query": {    "bool": {      "must": [        {          "multi_match": {            "query": "covid",            "fields": ["headline^4", "short_description"]          }        },        {          "function_score": {            "query": {              "multi_match": {                "query": "covid",                "fields": ["headline^4", "short_description"]              }            },            "functions": [              {                "filter": {                  "term": {                    "country.keyword": "US"                  }                },                "weight": 2              }, {                "field_value_factor": {                  "field": "timestamp",                  "factor": 2                }              }            ]          }        }      ]    }  }}

Ora i documenti recenti e quelli provenienti dal paese dell’utente riceveranno un punteggio più alto. Possiamo regolare questo equilibrio configurando i valori per i campi weight e factor.

Ricerche Fuzzy

Successivamente, correggiamo gli errori di scrittura nella query di ricerca.

In Elasticsearch, possiamo eseguire ricerche fuzzy per recuperare documenti che corrispondono a un termine specificato anche se ci sono lievi variazioni nell’ortografia o nei caratteri. Per fare ciò, possiamo semplicemente aggiungere un campo fuzziness alla nostra query. La nostra query finale diventa —

GET news/_search{  "query": {    "bool": {      "must": [        {          "multi_match": {            "query": "covi",            "fields": ["headline^4", "short_description"],            "fuzziness": 1          }        },        {          "function_score": {            "query": {              "multi_match": {                "query": "covi",                "fields": ["headline^4", "short_description"],                "fuzziness": 1              }            },            "functions": [              {                "filter": {                  "term": {                    "country.keyword": "US"                  }                },                "weight": 2              }, {                "field_value_factor": {                  "field": "timestamp",                  "factor": 2                }              }            ]          }        }      ]    }  }}

La correzione dell’ortografia è molto più complessa che semplicemente aggiungere fuzziness. Dai un’occhiata a questo post del blog se vuoi saperne di più.

Conclusioni

In questo post del blog, ci siamo addentrati nei dettagli di Elasticsearch, iniziando con un’analisi pratica di un set di dati di esempio e le basi della creazione di query di ricerca. Abbiamo demistificato le risposte di Elasticsearch e analizzato una query di ricerca di base, gettando le basi per una ricerca efficace.

Mentre esploravamo la ricerca lessicale, abbiamo riconosciuto alcune particolarità nel nostro approccio attuale alla ricerca. Per affrontare queste sfide, abbiamo introdotto il concetto di potenziamento e di sfocatura: due strumenti utili per affinare le nostre ricerche e gestire le complessità dei dati reali.

Man mano che concludiamo, considerate questo come una sosta durante il nostro percorso verso l’eccellenza nella ricerca. Nella prossima parte, approfondiremo le strategie avanzate per superare problemi specifici nel nostro approccio attuale alla ricerca. Preparatevi per l’affascinante mondo della ricerca semantica, dove l’attenzione si sposta dal semplice abbinamento delle parole chiave alla comprensione del significato che si cela dietro di esse, aprendo la strada a esperienze di ricerca più intuitive e consapevoli del contesto. Preparatevi a portare la vostra avventura con Elasticsearch al livello successivo!

Avete apprezzato il viaggio attraverso Elasticsearch? Seguitemi su VoAGI per altri articoli. Per piccole dosi di conoscenza (informazioni rapide su ciò che sto leggendo, cheatsheets, ecc.), seguitemi su LinkedIn con contenuti regolari in forma breve (ad esempio, mentre leggevo su Elasticsearch, ho discusso brevemente in un post di 5 minuti come funziona una particolare funzione di punteggio chiamata tf-idf). Restiamo connessi in questa esplorazione di tecnologia e dati!