MongoDB è un DBMS non relazionale, basato su un concetto dove viene messo come al primo posto la velocità. Un modo semplice per comprendere il suo funzionamento è pensare che si tratti di un tipo database realizzato per memorizzare degli oggetti. Gli oggetti sono essenzialmente dei JSON, chiamati BSON, e rappresentano i record chiamati document, contenuti all’interno delle tabella chiamate collection.

Nel seguente progetto di esempio parto da uno schema ER su SQL pre-realizzato per meglio comprendere l’idea generale della struttura della logica dell’applicativo.

Inizio gli sviluppi creando la prima entità ProdottoModel essendo l’entità principale del progetto e inserendo alcune proprietà che la rappresentano. L’attributo [BsonId] è necessario per identificare la primary key, definendola di tipo Guid facilitandomi così nella gestione.

										public class ProdottoModel
{
   [BsonId]
   public Guid Id { get; set; }
   public string Codice { get; set; }
   public string Descrizione { get; set; }
   public string UM { get; set; }
}
									

Eseguo un test di inserimento, semplicemente istanziando MongoClient e non specificando nessuna ConnectionString in modo che si colleghi al server in locale precedentemente installato. Nel dettaglio cerca un database in locale di nome pmgmt non trovandolo lo crea, la stessa cosa succede per le tabelle.

var client = new MongoClient();
IMongoDatabase db = client.GetDatabase("pmgmt");

var l = db.GetCollection("prodotti");
l.InsertOne(new ProdottoModel() {
    Codice = "0011494.01",                      
    Descrizione = "LATTE DI CAPRA P/S UHT - LT - 1",                     
    UM = "LT"
});

Visualizzo il risultato nel management utilizzando MongoDB Compass, installato durante l’installazione di MongoDB Community Server.

Aggiungo alla entità ProdottoModel la proprietà Famiglia di tipo FamigliaModel con all’interno la proprietà nome, ed eseguo un test di inserimento di una nuova riga.

l.InsertOne(new ProdottoModel()
{
    Codice = "0802720.01",
    Articolo = "PARMALAT YOG.0.1% MAGRO CR.FRUTTA - GR - 125 X 8",
    UM = "GR",
    Famiglia = new FamigliaModel() {  Nome = "YOGHURT" }
});

Come si può vedere nella seguente immagine, è possibile eseguire questo inserimento nonostante la proprietà famiglia non fosse presente nella entità ProdottoModel. E’ quindi possibile sviluppare un’applicazione senza dover definire lo schema ER come pre-requisito fondamentale. Tutto questo può suonare male, ma tutto ciò rende più flessibile le implementazioni senza dover pensare a query, join, view, insert e tutto quello che riguarda il mondo SQL.

Un’altra considerazione che può essere fatta riguarda, come in questo esempio, la proprietà Famiglia essendo comune a più prodotti viene duplicata, ci sarà quindi un maggior uso di spazio disco di un SQL DB ma l’altra faccia della medaglia è che il dato prodotto ha tutte le informazioni collegate senza bisogno di ricercarle o rielaborarle. Ora vediamo come inserire una proprietà a delle righe già inserite. Procedo alla lettura di tutti i dati e successivamente aggiungo un filtro.

// leggi tutti i prodotti
var lProdotti = l.Find(new BsonDocument()).ToList();

// cerca i prodotti della famiglia YOGHURT
var filtroYoghurt = Builders.Filter.Where(f => f.Famiglia != null && f.Famiglia.Nome == "YOGHURT")
var lProdottiYoghurt = l.Find(filtroYoghurt).ToList();

Come ultimo test aggiungo alla classe FamigliaModel una proprietà settore di tipo SettoreModel.

public class FamigliaModel
{
    public string Famiglia { get; set; }
    public SettoreModel Settore { get; set; }
}
public class SettoreModel
{
    public string Nome { get; set; }
}

Procedo con l’aggiornamento di tutti i prodotti della famiglia Yoghurt aggiungendo il settore Ultra freschi.

// aggiorna aggiungendo il settore
foreach (var item in lProdottiYoghurt)
{
    var filtroID = Builders.Filter.Eq("Id", item.Id);
    item.Famiglia.Settore = new SettoreModel() { Nome = "Ultra freschi" };
    l.ReplaceOne(filtroID, item);
}

In conclusione si può dire che non è esattamente il sistema perfetto per tutti i contesti, però in situazioni dove è necessario tempi di risposta molto veloci, anche a fronte di milioni di dati, o per applicazioni dove sono richiesti tempi di sviluppo ridotti, o non ci sono requisiti chiari, potrebbe essere la soluzione adatta.

appunti sullo sviluppo:

Ho utilizzato Visual Studio 2019 creando una nuova Console App (.NET Core). Prima di iniziare gli sviluppi ho installato localmente la versione gratuita MongoDB Community Server scaricandola dal sito ufficiale. Una volta creato l’applicazione ho installato, tramite NuGet, il pacchetto MongoDB.driver necessario per connettersi al database.