DATA SCALABLE SOLUTIONS FOR INDUSTRIAL APPLICATIONS (DASSIA) TUTORIAL HIVE Tutorial_Hive 1 di 24 1 ESPLORAZIONE DEI COMANDI DI HIVE Le attività della prima parte del tutorial sono orientate alla sperimentazione e alla familiarizzazione con i vari comandi di Hive illustrati nella parte teorica. Riprenderemo quindi i vari script utilizzati nelle slide e li eseguiremo con Hive per verificare ed approfondire il comportamento dei vari comandi. Il suggerimento, per questa fase è quello di non limitarsi ad eseguire gli script così come sono ma anche di provare a modificarli per familiarizzare con la grammatica dei comandi stessi. 1.1 Interfaccia Per interagire con HIVE useremo la gui disponibile sulla SandBox pronta distribuita da HortonWorks. Per accedere occorre raggiungere l'indirizzo ip assegnato alla vostra macchina virtuale seguito dall'indicazione della porta 8000. Ad esempio andremo a digitare sul browser http://192.168.1.103:8000/ Otterremo quindi l'home page della sandbox Per accedere alla gui dedicata ad Hive (denominata Beeswax) dovremo cliccare sulla seconda icona in alto a destra. Tutorial_Hive 2 di 24 Da questa schermata potremo scrivere il nostro script all'interno dall'area “Query Editor” ed eseguirlo con il pulsante verde in basso “Execute”. Avremo anche la possibilità di salvare i nostri script. La barra in alto ci sarà utile in fase di navigazione: • nel tab “My Queries” andremo a trovare tutte le queries che abbiamo salvato con il nostro utente (“Hue”); • nel tab “Saved Queries” andremo a trovare tutte le queries salvate da qualunque utente; • nel tab “History” è presente un riepilogo di tutte le queries che abbiamo mandato in esecuzione; • nel tab “Result” è presente un riepilogo dei risultati dell'ultima query mandata in esecuzione; • attraverso il tab “Databases” potremo esplorare i databases; • attraverso il tab “Tables” potremo esplorare tutte le tabelle presenti; • attraverso il tab “Settings” potremo andare a modificare eventuali opzioni. Occorrerà prestare attenzione al fatto che questa gui viene presentata a puro scopo formativo: potranno venire a presentarsi delle piccole incongruità tra le queries e/o gli script assegnati e i comportamenti ottenuti da parte di Hive. Tutorial_Hive 3 di 24 2 CREAZIONE DEL DATABASE Per iniziare a lavorare con Hive la prima cosa di cui abbiamo bisogno è creare un database dedicato. Possiamo creare il nostro primo database financials scrivendo CREATE DATABASE IF NOT EXISTS financials; Con questo comando il database viene creato all'interno del path dell'hdfs /apps/hive/warehouse possiamo eventualmente crearlo in una cartella dedicata andando ad aggiungere l'apposita destinazione nel comando appena presentato: CREATE DATABASE IF NOT EXISTS financials LOCATION '/user/hue/hive/financials_db'; in questo modo il database viene creato all'interno del path dell'hdfs /user/hue/hive/financials_db La scelta relativa alla destinazione fisica dei file che compongono il nostro database non influenza in alcun modo lo svolgimento del presente tutorial. Il dataset appena creato è rappresentato semplicemente da una cartella vuota: possiamo andare a verificare questa caratteristica attraverso il File Browser della nostra Sandbox. Tutorial_Hive 4 di 24 3 DATASET D'ESEMPIO Questi script sono basati principalmente sul dataset NYSE (New York Stock Exchange) che contiene i dati di scambio di alcuni titoli di borsa: NYSE_daily NYSE_dividends I dati corrispondono grossomodo al dump di due tabelle di un DB, il cui schema potrebbe essere rappresentato in questo modo per NYSE_daily a: exchange_col STRING, stock_symbol STRING, date STRUCT<year:INT, month:INT, day:INT>, stock_price_open FLOAT, stock_price_high FLOAT, stock_price_low FLOAT, stock_price_close FLOAT, stock_volume INT, stock_price_adj_close FLOAT e per NYSE_dividends a: exchange_col STRING, stock_symbol STRING, date STRUCT<year:INT, month:INT, day:INT>, dividends FLOAT Il file NYSE_daily è presente all'interno della cartella Tutorial_Hive 5 di 24 /user/hue/hive/data Il file NYSE_dividends è presente all'interno della cartella /user/hue/hive Per poter lavorare con questi dati la prima cosa che dobbiamo fare è analizzarli per poter capire la strategia più opportuna per importarli all'interno di una tabella e trattarli al fine di eseguire delle queries. Come possiamo notare dagli esempi dei dati sopra presentati possiamo subito notare delle differenze rispetto al normale formato dei dati testuali che Hive si aspetta di trattare: mentre solitamente Hive valuta come default: • \n separatore di linea • ^A rappresentato dalla stringa \001, separatore di colonna • ^B rappresentato dalla stringa \002, separatore dei valori negli struct e negli array o delle coppie chiave- valore nei map • ^C rappresentato dalla stringa \003, separatore inserito tra la singola coppia chiave-valore all'interno del map in questo caso abbiamo che: • \n separatore di linea • \t separatore di colonna • - separatore dei valori negli struct e negli array o delle coppie chiave-valore nei map È nostra cura, all'atto della definizione della tabella, andare a specificare correttamente questi separatori. Tutorial_Hive 6 di 24 4 TABELLA INTERNA ED ESTERNA 4.1 Creazione della Tabella Interna La prima query che andiamo a scrivere è quella legata alla creazione della tabella dedicata ad ospitare i dati relativi al file NYSE_dividends. Definiamo quindi i vari campi che Hive deve trattare e i differenti separatori individuati nel capitolo precedente. Queste indicazioni le inseriamo in una tabella denominata dividends all'interno del database financials. CREATE TABLE financials.dividends ( exchange_col STRING, stock_symbol STRING, date STRUCT<year:INT, month:INT, day:INT>, dividends FLOAT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY '-' STORED AS TEXTFILE ; L'esecuzione di questa query comporterà unicamente la creazione dello schema dei dati all'interno del metastore: non abbiamo infatti ancora provveduto ad importare alcun tipo di dato. 4.2 Importazione dei dati nella Tabella Interna Per importare i dati del file NYSE_dividends all'interno della tabella interna dividends appena creata dobbiamo indicare ad Hive la sorgente dei dati di nostro interesse: LOAD DATA INPATH '/user/hue/hive/NYSE_dividends' OVERWRITE INTO TABLE financials.dividends; con questa query indichiamo ad Hive di caricare i dati presenti all'interno del file NYSE_dividends e sovrascrivere eventuali dati già contenuti all'interno della tabella. Se non avessimo utilizzato la keyword OVERWRITE i dati importati sarebbero stati eventualmente accodati a quelli già presenti. Con questo comando abbiamo ottenuto un effetto fondamentale: lo spostamento del file NYSE_dividends all'interno della cartella dividends che rappresenta la tabella nel database financials. Quanto accaduto è riscontrabile utilizzando il File Browser della nostra Sandbox. Contenuto della cartella /user/hue/hive prima della query Tutorial_Hive 7 di 24 Contenuto della cartella /user/hue/hive dopo la query Contenuto della cartella che rappresenta la tabella dopo la query 4.3 Tabella Esterna La seconda query che andiamo a scrivere è quella da utilizzare per importare i dati contenuti nel file NYSE_daily all'interno di una tabella esterna non partizionata. In questo modo i dati restano fisicamente all'interno della cartella precedentemente indicata ma possiamo utilizzarli per realizzare le nostre queries successive. CREATE EXTERNAL TABLE financials.stock ( exchange_col STRING, stock_symbol STRING, date STRUCT<year:INT, month:INT, day:INT>, stock_price_open FLOAT, stock_price_high FLOAT, stock_price_low FLOAT, stock_price_close FLOAT, stock_volume INT, stock_price_adj_close FLOAT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY '-' LOCATION '/user/hue/hive/data' ; Con questa query stiamo creando la tabella stock all'interno del database financials e i cui dati sono localizzati Tutorial_Hive 8 di 24 all'interno della cartella /user/hue/hive/data. Stiamo inoltre definendo i vari campi che Hive deve trattare e i differenti separatori individuati nei paragrafi precedenti. Utilizzando ancora una volta il File Browser della nostra Sandbox possiamo verificare che i file di origine, a seguito della query, non subiscono delle alterazioni e non vengono spostati in altre posizioni. La cosa a cui occorre prestare attenzione quando si vanno a creare le tabelle esterne è l'eventuale presenza di file di dati spuri all'interno della cartella che indichiamo come sorgente dei dati. Tutorial_Hive 9 di 24 5 QUERIES 5.1 SELECT semplici e con clausola limit Una delle prime queries che si può eseguire una volta che abbiamo creato le nostre tabelle è la visualizzazione di tutti i record presenti. Ad esempio: SELECT * FROM financials.stock; mostra tutti i record all'interno della tabella stock nel database financials. L'output mostrato è simile a questo: dove possiamo notare quale sia l'intero contenuto della nostra tabella. Con i pulsanti possiamo poi scorrere tra le varie pagine che ci vengono proposte. È sicuramente più conveniente utilizzare la clausola LIMIT che ci consente appunto di limitare l'output visualizzato: ad esempio con SELECT * FROM financials.stock LIMIT 5; andiamo a visualizzare solo le prime 5 righe presenti nella tabella. 5.2 SELECT con clausola WHERE A questo punto possiamo iniziare a eseguire delle queries con la clausola WHERE: esattamente come nel SQL essa verifica che una certa condizione sia rispettata dal contenuto di uno o più campi di una certa riga, se la condizione è verificata verranno effettivamente mostrati i campi specificati all'interno della SELECT. Ad esempio, se volessimo mostrare il contenuto di tutte le righe della tabella in cui l'anno è diverso dal 2009, Tutorial_Hive 10 di 24 possiamo utilizzare SELECT * FROM financials.stock WHERE date.year!=2009; il risultato ottenuto è: dove possiamo notare che effettivamente non vengono mostrate tutte le righe che contengono, all'interno della data, un anno uguale a 2009. È ovviamente possibile concatenare, alla clausola WHERE, più condizioni andando ad utilizzare i normali operatori booleani. Utilizzando SELECT * FROM financials.stock WHERE date.year<2000 AND date.month==10; andiamo a visualizzare solo quei record nei quali l'anno della data è inferiore al 2000 e il mese corrispondente è ottobre 5.3 GROUP BY Anche in Hive possiamo raggruppare l'output di una SELECT in base a specifici campi all'interno della tabella. Se vogliamo avere un riepilogo dei simboli presenti all'interno della tabella stock possiamo scrivere: SELECT stock_symbol FROM financials.stock GROUP BY stock_symbol; In questo modo otteniamo questo output Tutorial_Hive 11 di 24 5.4 SELECT con operatori e funzioni Una volta ottenuto il nostro output precedente immaginiamo di voler anche conoscere quale sia stata la media dei titoli scambiati. Questa operazione possiamo svolgerla utilizzando una delle funzioni implementate in Hive. Ad esempio: SELECT stock_symbol, avg(stock_volume) FROM financials.stock GROUP BY stock_symbol; in questo modo per ogni simbolo otteniamo anche la media di tutto il volume di scambi che l'ha interessato nelle varie sedute 5.5 SELECT con alias Come possiamo notare nell'output precedente abbiamo che alla colonna che riporta la media dei volumi scambiati viene assegnata un'etichetta poco chiara. Possiamo quindi decidere di assegnare delle specifiche etichette alle diverse colonne risultato della SELECT utilizzando la keyword AS seguita dal nome dell'etichetta per uno o più campi di nostro interesse. Ad esempio possiamo voler chiamare la colonna dei simboli symbol e la colonna delle medie average. Possiamo ottenere questo risultato andando a eseguire la seguente query: SELECT stock_symbol as symbol, avg(stock_volume) as average FROM financials.stock GROUP BY stock_symbol; il cui risultato è Tutorial_Hive 12 di 24 5.6 GROUP BY e HAVING A questo punto possiamo decidere di eseguire dei raggruppamenti e di mostrare unicamente quelli che hanno una media di scambi che rispetti una certa condizione, ad esempio che il volume d'azioni scambiate sia superiore ai 250000. Questa operazione si può compiere utilizzando la clausola HAVING del GROUP BY. Nell'esempio appena citato la query corrispondente è SELECT stock_symbol as symbol, avg(stock_volume) as average FROM financials.stock GROUP BY stock_symbol HAVING average > 250000; il cui risultato risulta essere 5.7 SELECT Concatenati Può occorrere, in alcuni casi, dover concatenare una SELECT al risultato di un'altra SELECT. In questo caso si parla di SELECT concatenati o annidati. Ipotizziamo di voler contare quante siano le righe nella nostra tabella che contengono, nel campo data, un anno differente da 2009. Per arrivare a questo risultato dobbiamo: • trovare tutte le righe che hanno un campo differente da 2009; • contarle. Queste due operazioni corrispondo a due differenti SELECT: • SELECT * FROM financials.stock WHERE date.year!=2009; • SELECT count(1) FROM …; Tutorial_Hive 13 di 24 È facile intuire che il risultato della prima SELECT deve essere l'oggetto del FROM della seconda. La scrittura di questa query segue i dettami visti fin'ora: SELECT count(1) FROM (SELECT * FROM financials.stock WHERE date.year!=2009) lines; dove però siamo costretti a specificare un alias che definisca la SELECT annidata che andiamo a scrivere: in questo caso la parola lines indica tutta la SELECT all'interno delle parentesi tonde. Il risultato è il seguente: Possiamo ovviamente anche qui assegnare una differente etichetta al campo mostrato utilizzando la keyword AS: SELECT count(1) as counter FROM (SELECT * FROM financials.stock WHERE date.year!=2009) lines; La possibilità di andare a specificare degli alias per i risultati della SELECT è particolarmente utile ad esempio quando si sfruttano dei SELECT concatenati complessi. Ad esempio: FROM ( SELECT lower(stock_symbol) as lower_sym, stock_volume as volume, date.year as year FROM financials.stock ) sd SELECT sd.year as year, sd.lower_sym as symbol, sd.volume as volume WHERE sd.volume > (1000000) dove possiamo indifferentemente posizionare il FROM prima o dopo il SELECT e dove utilizziamo poi l'alias associato alla SELECT più interna e ai suoi campi per accedere dalla SELECT più esterna. In questo caso: • prima eseguiamo una SELECT alla quale ci riferiamo utilizzando l'alias sd avente tre campi lower_sym, volume e year; • in seguito eseguiamo una SELECT dove accediamo a questi campi rinominandoli rispettivamente in symbol, volume e year ma visualizzando solo quei record che hanno avuto un volume di scambio superiore al milione di azioni e modificando l'ordine di visualizzazione. Il risultato che otteniamo è: Tutorial_Hive 14 di 24 Analogo risultato l'avremmo ottenuto utilizzando la query: SELECT sd.year as year, sd.lower_sym as symbol, sd.volume as volume FROM ( SELECT lower(stock_symbol) as lower_sym, stock_volume as volume, date.year as year FROM financials.stock ) sd WHERE sd.volume > 1000000 5.8 Le VISTE Quando si tratta di andare ad eseguire numerose SELECT concatenate può essere opportuno avere un meccanismo per la quale andiamo a memorizzare su Hive una specifica SELECT in maniera da poterle richiamare al momento più opportuno: questa memorizzazione viene denominata vista (o view). In particolare quando creiamo una vista indichiamo ad Hive di mantenere in memoria il risultato di una SELECT come se fosse una nuova tabella: in realtà però accade che quando si richiama una vista la SELECT in essa memorizzata viene rieseguita. Decidiamo di salvare quindi una vista, denominata symbol, all'interno del nostro database financials che contenga i simboli dei titoli azionari raggruppati e il numero medio di titoli scambiati. Otteniamo questo risultato con: CREATE VIEW financials.symbol AS SELECT stock_symbol, avg(stock_volume) as average FROM financials.stock GROUP BY stock_symbol; Per vedere cos'è successo possiamo eseguire la seguente query use financials; show tables; essa ci mostra che tra le tabelle del database financials effettivamente è stata aggiunta una vista symbol. Tutorial_Hive 15 di 24 symbol risulta però essere unicamente un riferimento a una SELECT, non sono presenti dati di alcun tipo memorizzati nell'HDFS. Possiamo accertare questo fatto andando sulla tab Tables di beeswax. Selezioniamo, dal menù a tendina di sinistra il database financials e vediamo anche qui le tre tabelle che lo compongono: Possiamo notare che symbol, rispetto ad esempio a dividends, è una vista e non una vera tabella provando a esplorare i dati al suo interno. Se clicchiamo su dividends vediamo che esiste, oltre alla tab Columns anche una tab Sample: e selezionando la tab Sample vediamo i nostri dati: Se invece clicchiamo, dalla tab Tables, la tabella symbol, quello che otteniamo è questa visualizzazione Tutorial_Hive 16 di 24 dove non è possibile andare a esplorare i dati. Dal menù a sinistra è però disponibile un comando Browse Data selezionandolo abbiamo che viene effettivamente lanciata la SELECT da noi memorizzata nella vista. 5.9 ORDER BY Una delle situazioni più comuni che ci si può trovare ad affrontare è l'ordinamento dei dati. Vogliamo ora ordinare i dati della vista appena creata in ordine decrescente rispetto alla media. Per farlo lanciamo la query: SELECT * FROM financials.symbol ORDER BY average DESC; il risultato ottenuto è il seguente: Possiamo anche ordinare i risultati di una certa SELECT utilizzando più di un campo di riferimento. Vogliamo ora selezionare tutte le colonne della tabella dividends ordinando però rispetto al dividendo decrescente e in ordine alfabetico per quanto riguarda i titoli. Otteniamo questo risultato con: SELECT * FROM financials.dividends ORDER BY dividends DESC, stock_symbol ASC; Tutorial_Hive 17 di 24 un estratto del risultato che abbiamo è il seguente dove si evidenzia, nella riga 20 e 21, che le righe oltre ad essere ordinate in maniera decrescente rispetto al campo dividends sono ordinate in maniera crescente, in seconda istanza, rispetto al campo stock_symbol. 5.10 CASE … WHEN … THEN Con Hive possiamo utilizzare un costrutto CASE … WHEN … THEN per associare ai campi di una colonna di una tabella o di una vista dei valori predeterminati al verificarsi di differenti condizioni. Quello che vogliamo ottenere è realizzare una nuova vista, chiamata dimension, che partendo dalla vista symbol le aggiunga un ulteriore campo chiamato dimension a cui possono essere associati i seguenti valori: low: se la media dei titoli scambiati è inferiore al milione middle: se la media dei titoli scambiati è maggiore o uguale a un milione ma inferiore ai cinque milioni high: se la media dei titoli scambiati è maggiore o uguale ai cinque milioni ma inferiore ai dieci milioni very high: se la media dei titoli scambiati è maggiore o uguale ai dieci milioni La query che dobbiamo andare a scrivere è la seguente: CREATE VIEW financials.dimension AS SELECT stock_symbol, average, CASE WHEN average < 1000000 THEN 'low' WHEN average < 5000000 THEN 'middle' WHEN average < 10000000 THEN 'high' ELSE 'very high' END as dimension FROM financials.symbol; Per poter poi verificare che abbiamo ottenuto il risultato desiderato scriviamo: SELECT * FROM financials.dimension; il cui risultato è Tutorial_Hive 18 di 24 6 TABELLA PARTIZIONATA 6.1 Creazione della tabella A partire dalla vista appena creata decidiamo di realizzare una tabella partizionata che contenga gli stessi campi esposti precedentemente dove però la colonna delle dimensioni diventa la partizione sulla quale vogliamo agire. La prima cosa da fare è creare la nostra tabella: CREATE TABLE financials.dimension_part ( stock_symbol STRING, average FLOAT ) PARTITIONED BY (dimension STRING); con questa query abbiamo creato all'interno del metastore lo schema associato. Possiamo visualizzarlo utilizzando il tab Tables di beeswax dove vediamo che è stato anche aggiunto un tab Partition Columns. Nell'HDFS viene invece creata una cartella vuota che rappresenta la nostra tabella partizionata all'interno del path che rappresenta il nostro database (la localizzazione dipende da come è stato costruito il database al capitolo 2). 6.2 Riempimento della tabella Riempiamo ora la tabella partizionata secondo quanto ci proponiamo di fare. INSERT OVERWRITE TABLE financials.dimension_part PARTITION (dimension) SELECT stock_symbol, average, dimension FROM financials.dimension; Il risultato di questa query1 è visibile andando a navigare nel File Browser della Sandbox. La cartella vuota creata nel punto precedente viene popolata di altre sottocartelle che rappresentano le differenti partizioni riscontrate: 1 A seconda della configurazione di Hive questa query potrebbe fallire. Si raccomanda – eventualmente – di sostituirla con la seguente dove si va a indicare in maniera esplicita il campo relativo alla partizione: INSERT OVERWRITE TABLE financials.dimension_part PARTITION (dimension='dimension') SELECT stock_symbol, average FROM financials.dimension; Tutorial_Hive 19 di 24 All'interno di ognuna di queste cartelle sono presenti uno o più files di dati. Aprendone uno possiamo notare che non sono presenti dati che rappresentano la partizione ma unicamente dei dati che rappresentano le colonne ordinarie. Per l'implementazione della tabella partizionata dobbiamo sempre ricordare che la colonna (o le colonne) che rappresenta la partizione deve sempre essere selezionata per ultima. Se avessimo voluto partizionare rispetto alla colonna delle medie ad esempio avremmo dovuto scrivere: INSERT OVERWRITE TABLE financials.average_part PARTITION (dimension) SELECT stock_symbol, dimension, average FROM financials.dimension; Dobbiamo tenere in considerazione che la Sandbox che stiamo utilizzando è configurata in maniera minimale e per puro uso dimostrativo: non sono supportate queries che portano alla realizzazione di un numero elevato di partizioni o molto complesse. Questa limitazione è dovuta a problematiche di timeout e swap del sistema. Per realizzare questo tipo di queries è sempre consigliabile utilizzare la CLI. Tutorial_Hive 20 di 24 7 JOIN In Hive possiamo andare a realizzare i più comuni JOIN. L'implementazione è però ancora non completa e alcune funzionalità non sono supportate. Una delle caratteristiche più limitanti è la possibilità di eseguire unicamente degli equity join. 7.1 Inner JOIN Andiamo a realizzare prima di tutto un Inner JOIN dove vogliamo mettere a confronto i prezzi di chiusura di due titoli azionari, ad esempio CLI e CHP nelle medesime date a partire dalla tabella stock. La nostra query è la seguente: SELECT a.date, a.stock_price_close as CLI, b.stock_price_close as CHP FROM financials.stock a JOIN financials.stock b ON a.date = b.date WHERE a.stock_symbol = 'CLI' AND b.stock_symbol = 'CHP'; Il risultato che otteniamo è: 7.2 LEFT e RIGHT OUTER JOIN In Hive sono supportati anche i JOIN dove vengono mostrati tutti i record di una tabella (a sinistra o a destra del JOIN) che corrispondolo al vincolo imposto dalla clausola WHERE. Se i corrispondenti campi della tabella di (destra o sinistra a seconda del JOIN) non sono valorizzati o non contengono valori validi per la condizione specificata dalla clausola ON viene restituito un NULL. Procediamo a realizzare una query con LEFT OUTER JOIN dove vogliamo visualizzare per il simbolo CLI: • la data; • il simbolo; • il prezzo di chiusura; • il dividendo del titolo in quella data. È chiaro che quello che dobbiamo fare è un JOIN tra le due tabelle stock e dividends. La query da andare a scrivere è: SELECT a.date, a.stock_symbol, a.stock_price_close, b.dividends FROM financials.stock a LEFT OUTER JOIN financials.dividends b ON a.date = b.date AND a.stock_symbol = b.stock_symbol Tutorial_Hive 21 di 24 WHERE a.stock_symbol = 'CLI'; dove, utilizzando un LEFT OUTER JOIN, chiediamo ad Hive di sostituire con un NULL il valore restituito per i dividendi se non viene trovato il corrispondente campo nella tabella dividends. Una porzione del risultato è la seguente: Avremmo potuto ottenere il medesimo risultato utilizzando un RIGHT OUTER JOIN 2 e invertendo la posizione delle due tabelle: SELECT a.date, a.stock_symbol, a.stock_price_close, b.dividends FROM financials.dividends b RIGHT OUTER JOIN financials.stock a ON a.date = b.date AND a.stock_symbol = b.stock_symbol WHERE a.stock_symbol = 'CLI'; In questi casi abbiamo utilizzato delle condizioni specifiche nelle clausole ON collegate da AND: è necessario far presente che non è possibile utilizzare differenti operatori booleani per la concatenazione di condizioni nella specifica delle clausole ON. 7.3 LEFT SEMI JOIN Nel LEFT SEMI JOIN abbiamo che vengono mostrati tutti quei record corrispondenti alla tabella a sinistra solo se i record della tabella di destra rispecchiano correttamente la clausola ON. Se vogliamo quindi ottenere • la data; • il simbolo; • il prezzo di chiusura; eliminando però tutti quei campi della tabella stock che corrispondono ai dati non validi secondo la clausola ON della tabella dividends, possiamo scrivere la query: SELECT a.date, a.stock_symbol, a.stock_price_close FROM financials.stock a LEFT SEMI JOIN financials.dividends b ON a.date = b.date AND a.stock_symbol = b.stock_symbol WHERE a.stock_symbol = 'CLI'; otteniamo il risultato: 2 All'interno della macchina virtuale assegnata la query memorizzata potrebbe essere differente e non funzionare Tutorial_Hive 22 di 24 Aver parlato del LEFT SEMI JOIN ci da modo di specificare che in Hive non è implementato il RIGHT SEMI JOIN. Tutorial_Hive 23 di 24 8 ESERCIZI Dopo aver familiarizzato con i comandi di Hive è giunto il momento di sperimentare i comandi su altri dati. Nella macchina virtuale sono presenti due file (access_log_Aug95 e access_log_Jul95) che contengono i log di accesso ad un sito della Nasa durante i mesi di luglio ed agosto del 1995. Il formato è analogo a quello visto durante la prima giornata. E' dunque possibile sperimentare su di essi i comandi di Hive, magari provando a riprodurre gli esercizi scritti in MapReduce. Ad esempio Elenco dei client più attivi Elenco delle risorse più richieste Filtro sulle date Istogramma sul traffico nei diversi giorni Tutorial_Hive 24 di 24