Tutorial > Primi passi con FaunaDB su Ubuntu 20.04

Primi passi con FaunaDB su Ubuntu 20.04

Pubblicato il: 22 febbraio 2021

Database Sviluppo Ubuntu

Introduzione

FaunaDB è un database "cloud as a service" serverless e distribuito a livello globale. FaunaDB salva le entità come documenti appartenenti a delle collezioni e permette di essere usato su applicazioni senza server.

In questa guida, ti spiegheremo come procedere nei primi step con il database FaunaDB, in seguito alla sua installazione su un server Ubuntu 20.04. Verranno inoltre mostrati alcuni esempi del linguaggio di query della shell di FaunaDB, prendendo come caso d'uso la costruzione di una collezione di brani da salvare nel database.

Installazione della shell Fauna

Dopo aver creato un account tramite la procedura di registrazione di FaunaDB, puoi installare la Shell Fauna sulla tua macchina.

A questo punto potrai connetterti al tuo server tramite una connessione SSH. Se non l’hai ancora fatto, ti consigliamo di seguire la nostra guida per connetterti in sicurezza con il protocollo SSH. In caso di server locale puoi passare al punto successivo e aprire il terminale del tuo server.

Per installare Fauna sul tuo server, puoi usare il comando npm:

$ npm install -g fauna-shell

Login nell'account FaunaDB

Il primo passo, dopo aver aperto la shell di FaunaDB, è procedere con l'autenticazione nel tuo account di Fauna.

Per farlo, inserisci all'interno della shell, il seguente comando:

$ fauna cloud-login

A questo punto, ti verrà chiesto di inserire le tue credenziali per l'accesso. Inserite per la prima volta, la Shell le memorizzerà in un file di configurazione nel percorso $HOME/.fauna-shell.

Creare un nuovo database con Fauna

Possiamo creare diversi database a seconda dell'impiego per i quali sceglieremo di utilizzarli.

Come in altri gestori di database, sarà sufficiente un semplice comando all'interno della shell, che nel nostro caso sarà:

$ fauna create-database ilmio_database

Nota: nell'esempio "ilmio_database" è il nome che abbiamo scelto di dare al DB creato, ma è possibile ovviamente assegnare qualunque altro nome.

Utilizzare FaunaDB e costruire i primi oggetti

Per scegliere, in primis, quale database utilizzare, si ricorre al comando:

$ fauna shell ilmio_database

Se il database è stato creato correttamente, dovresti ottenere un prompt di conferma.

Una volta nella shell, puoi iniziare creando la tua prima collezione:

ilmio_database> CreateCollection({ name: "brani" })

Nell'esempio, si immagina di costruire una collezione di brani da salvare nel database.

Dopo il comando, la shell restituirà delle informazioni, chiamate metadati, sulla collezione appena creata.

Un altro passo, è fornire un indice per trovare facilmente i brani salvati nel tuo DB in base al titolo:

ilmio_database> CreateIndex({
	name: "brani_per_titolo",
	source: Collection("brani")
	terms: [{ field: ["data", "title"] }]
})

Manipolare i dati

Aggiungere dati al database

Creato lo schema, puoi procedere a creare il primo documento della tua collezione:

ilmio_database> Create(
Collection("brani"),
{data: { title: "Luna" } }
)

L'output che dovresti ottenere è un responso sul documento appena registrato:

{ ref: Ref(Collection("brani"), "207089183860195845"),
  ts: 1533754485757944,
  data: { titolo: "Luna" } }

Potresti anche necessitare di inserire più brani, usando la funzione Map:

ilmio_database> Map(
  [
    "Luna",
    "I giardini di marzo",
    "Rebel Rebel"
  ],
  Lambda("titolo_brano",
    Create(
      Collection("brani"), { data: { titolo: Var("titolo_brano") } }
    )
  )
)

Nell'esempio:

  • Map è un array di brani che si vogliono registrare nel database;
  • Lambda è una funzione anonima che accetterà il parametro "titolo_brano" e lo riutilizzerà come valore del campo titolo nel nuovo documento inserito.

Al termine, riceveremo un ouput simile a quello indicato precedentemente ma ripetuto tre volte per tutti e tre i documenti salvati con il comando Map.

[ { ref: Ref(Collection("brani"), "207089200754854408"),
    ts: 1533754501878440,
    data: { titolo: "Luna" } },
  { ref: Ref(Collection("brani"), "207089200754853384"),
    ts: 1533754501878440,
    data: { titolo: "I giardini di marzo" } },
  { ref: Ref(Collection("brani"), "207089200754852360"),
    ts: 1533754501878440,
    data: { titolo: "Rebel Rebel" } } ]

Aggiornare i dati nel database

Per l'aggiornamento dei campi di un documento, registrato in una collezione della base di dati, puoi utilizzare il comando Update:

ilmio_database> Update(
  Ref(Collection("brani"), "207089183860195845"),
  { data: { titolo: "Kalimba de Luna" } }
)

All'interno del comando, nell'esempio:

  • La prima stringa serve a identificare un documento della collezione brani con ID corrispondente a quello indicato;
  • La seconda stringa serve a indicare che vuoi aggiornare il campo titolo di quel documento, inserendo il nuovo valore Kalimba de Luna.

Cancellare documenti o collezioni

Come hai potuto apprendere, FaunaDB rappresenta i dati come dei documenti appartenenti a delle collezioni. Per fare un paragone con SQL, questa procedura corrisponderebbe a salvare dei record all'interno delle tabelle.

Quando vuoi cancellare dei dati, hai a disposizione una procedura per "svuotare" una collezione da tutti i suoi documenti.

Il primo step consiste nel costruire un indice che punti a tutti gli elementi della collezione:

ilmio_database> CreateIndex({
  name: "tutti_brani",
  source: Collection("brani")
})

Non avendo specificato dei terms, l'indice punterà a tutti i documenti presenti nella collezione brani.

Ora, è il momento di procedere con la cancellazione di tutti gli elementi, tramite il comando Map concatenato con una funzione di cancellazione:

ilmio_database> Map(
  Paginate(
    Match(Index("tutti_brani"))
  ),
  Lambda("X", Delete(Var("X")))
)

Nell'esempio che puoi vedere sopra:

  • Map prenderà tutti i documenti puntati dall indice tutti_brani
  • Lambda è una funzione che eseguirà la cancellazione degli elementi puntati.

A questo punto, avrai privato una collezione di tutti i suoi elementi ma, a livello di dati, avrai solo eliminato le istanze e non la struttura creata. Per procedere, nel caso non ne avessi più bisogno, dovrai cancellare anche la collezione e l'indice.

Per far ciò, basterà un comando Delete:

ilmio_database> Delete(Collection("brani"))
ilmio_database> Delete(Index("tutti_brani"))

Con questa coppia di comandi, avrai cancellato la collezione brani e, successivamente, l'indice associato a tale collezione.

Ricavare i dati dal database Fauna tramite le query

Ricavare tutti i documenti di una collezione e usare gli indici

A ogni documento, alla sua creazione, viene associato un ID univoco che potrà essere utilizzato per identificare quell'entità all'interno delle collezioni.

Una prima semplice ricerca a cui potresti ricorrere è quella dell'ID del documento interessato. Per farlo, utilizza il comando:

ilmio_database> Get(Ref(Collection("brani"), "207089200754852360"))

Questo ID dovrebbe corrispondere a quello del brano "Rebel Rebel", inserito precedentemente nella collezione brani.

L'output ottenuto, dovrebbe essere simile:

{ ref: Ref(Collection("brani"), "207089200754852360"),
  ts: 1533754501878440,
  data: { title: "Rebel Rebel" } }

Un'altra possibilità è usare un indice, definito precedentemente nella guida.

ilmio_database> Get(
Match(
	Index("brani_per_titolo"),
		"I giardini di marzo"
		)
	)

In questo esempio, è stato cercato il brano "I giardini di marzo" tramite l'indice "brani_per_titolo". Il database restituirà questo output:

{ ref: Ref(Collection("brani"), "207089200754853384"),
  ts: 1533754501878440,
  data: { title: "I giardini di marzo" } }

Se invece volessi ricavare tutti i dati da una collezione del DB, senza applicare alcun filtro, ti basterà utilizzare un comando con l'ausilio di un indice, come hai visto in precedenza.

ilmio_database> CreateIndex({
  name: "tutti_brani",
  source: Collection("brani")
})

L'indice tutti_brani seleziona ogni documento della collezione brani. Successivamente, ricorri al comando:

Map(
  Paginate(
    Match(Index("tutti_brani"))
  ),
  Lambda("X", Get(Var("X")))
)

Nel codice, la funzione Lambda applicherà, sull'indice tutti_brani, la funzione Get.

Filtro per corrispondenza di valori

Puoi anche cercare dei documenti che abbiano un campo corrispondente a un determinato valore, specificato da te.

In primis, inizia, come sempre, definendo un indice:

ilmio_database> CreateIndex({
	name: "brani_per_anno",
	source: Collection("brani")
	terms: [{ field: ["data", "anno"] }]
})

Successivamente, puoi applicare un comando simile:

ilmio_database>
	Map(
  Paginate(
    Match(Index("brani_per_anno"), 2020)
  ),
  Lambda("X", Get(Var("X")))
)

Con questa query, avrai selezionato i brani appartenenti all'indice brani_per_anno, selezionando solo quelli dell'anno 2020.

Puoi fare una query simile, filtrando i brani NON con anno diverso dal 2020.

Map(
  Paginate(
    Difference(
      Match(Index("tutti_brani")),
      Match(Index("brani_per_anno"), 2020)
    )
  ),
  Lambda("x", Get(Var("x")))
)

La diversità, in questo caso, è nell'uso della funzione Difference.

Filtro per confronto

Altri filtri applicabili sono quelli sul confronto di valori di un campo con un valore definito da te.

Riprendendo l'indice brani_per_anno, puoi applicare un filtro che non si basi solo sul segn di uguaglianza ma anche sul segno maggiore o minore.

Map(
  Paginate(
    Match(Index("brani_per_anno")),
    { after: 2010 }
  ),
  Lambda("x", Get(Select(1, Var("x"))))
)

Nell'esempio, la specifica after serve a considerare i valori maggiori o uguali del valore 2010 .

Aggregare i dati

Con l'ausilio degli indici, ti sarà possibile anche aggregare i dati utilizzando degli stratagemmi che permettano di ricavare i massimi o minimi valori di un raggruppamento di valori.

CreateIndex({
  name: "brani_per_artista",
  source: Collection("brani"),
  values: [{ field: ["data","artista"] }]
})

Il primo indice, colleziona i brani per artista:

CreateIndex({
  name: "brani_per_lunghezza",
  source: Collection("brani"),
  terms: [{ field: ["data","artista"] }],
  values: [{ field: ["data","lunghezza_traccia"] }]
})

Immaginando di avere un campo per ogni brano per rappresentare la lunghezza di quella traccia, il secondo indice seleziona la durata per ciascun titolo. Successivamente, li mette in ordine partendo da quello con la durata maggiore.

Infine, tramite le funzioni, recupererai i brani, raggruppati per artista, indicando per ognuno di essi, la lunghezza della traccia con durata maggiore:

Map(
  Paginate(
    Distinct(
      Match(Index("brani_per_artista"))
    )
  ),
  gid => Get(
    Match(Index("brani_per_lunghezza"), Gid)
  )
)

Conclusioni

Ora dovresti avere le basi per poter interagire al meglio con FaunaDB e utilizzarlo per aumentare le prestazioni e la sicurezza delle tue applicazioni serverless. 

Ti consigliamo di approfondire i concetti legati a questo database visitando la documentazione ufficiale di FaunaDB e scoprire le Funzioni e i Tipi di dati di FaunaDB a tua disposizione.