C# la gestione delle Collection di MongoDB Community

Articolo che fornisce una panoramica sulla gestione delle Collection di MongoDB in .Net usando il linguaggio di programmazione C#.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

In questo articolo vedremo come gestire le collection di un database MongoDB, in particolare della versione Community, che si installa sul computer ed è gratuita.
Le collection permettono di gestire i vari documenti, sono come le tabelle per i database relazionali .
In questo articolo, vedremo tramite progetto di tipo “Windows Application” come rilevare informazioni e gestire le collection all’interno di un database.

Stesura del codice

Dopo aver creato un progetto di tipo “Windows Forms” con l’ultima versione del Framework e con l’ambiente di sviluppo Visual Studio 2022 Community o versione successiva, aggiungiamo alla form un pulsante, in modo da eseguire il codice nell’evento click del pulsante.
Codice che può essere eseguito anche nell’evento load della form, in base a come preferisce il lettore.
Dopo aver aggiunto il pacchetto a “MangoDB.Driver” (qui Tutorial .Net MongoDB CRUD : C# le operazioni CRUD sul database MongoDB - Prima parte | Database l’articolo introduttivo operazioni CRUD ) passiamo in visualizzazione codice, ed in alto, sopra ad ogni dichiarazione inseriamo lo spazio dei nomi per utilizzare le classi di gestione del database MongoDB.
Di seguito il frammento di codice delle suddette operazioni.

C#
using MongoDB.Bson;
using MongoDB.Driver;

Ritorniamo in visualizzazione grafica, e facciamo doppio click su un pulsante. 
Nell’evento click del pulsante, tramite il metodo “ListCollectionNames” dell’oggetto IMongoDBClient, rileviamo i nomi delle collection del database selezionato.
Di seguito si riporta il frammento di codice delle suddette operazioni.

C#
private void BtnTutteCollection_Click(object sender, EventArgs e)
{
   try
   {
       //Oggetto client MongoDB
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       //Seleziono il database dal quale rilevare le collection
       var database = clientMongoDB.GetDatabase("Amministrazione");
       //Ottengo il nome delle collection presenti nel database
       var collectionNames = database.ListCollectionNames().ToList();
       //Controllo se ci sono collection nel database
       if (collectionNames.Count == 0)
       {
           MessageBox.Show("Nessuna collection trovata nel database 'Amministrazione'.");
           return;
       }
       //Visualizzo i nomi delle collection
       string collections = string.Join(Environment.NewLine, collectionNames);
       MessageBox.Show("Collezioni presenti nel database 'Amministrazione':\n" + collections);
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Il codice rileva tutte le collection presenti in un database.
Nel caso che si desiderano ottenere altre informazioni, tipo nome collection, informazioni sulla collection, il tipo e le opzioni, possiamo ottenerle dal metodo “ListCollections” della classe  “IMongoDataBase”, tramite determinate proprietà.
Di seguito si riporta un frammento di codice che rileva alcune informazioni sulle collection. 

C#
 private void BtnInformazioniCollection_Click(object sender, EventArgs e)
 {
     try
     {
         //Oggetto del client MongoDB
         var clientMongoDB = new MongoClient("mongodb://localhost:27017");
         //Seleziono il database dal quale rilevare le collection
         var database = clientMongoDB.GetDatabase("Amministrazione");
         //Per ogni collection rilevo informazioni
         database.ListCollections().ForEachAsync(collection =>
         {
             MessageBox.Show($"Collection: {collection["name"]}" +  $"  Opzioni: {collection["options"]}" + $"  Tipo: {collection["type"]}" + $"  informazioni: {collection["info"]}");
         });
         //Visualizza nella griglia
         DgvDati.DataSource = null;  
         DgvDati.DataSource = database.ListCollections().ToList().Select(d => new
         {
             Nome = d["name"].ToString(),
             Opzioni = d["options"].ToString(),
             Tipo = d["type"].ToString(),
             informazioni = d["info"].ToString()
         }).ToList();
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }


Nel caso che invece desideriamo sapere quanti documenti sono presenti in una collection, tramite il metodo “CountDocuments” possiamo rilevare il numero dei documenti sono presenti in una collection.

Si riporta il frammento di codice delle suddette operazioni.

C#
private void BtnNumeroDocumenti_Click(object sender, EventArgs e)
{
    try
    {
        //Oggetto del client MongoDB
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        //Seleziono il database dal quale rilevare le collection
        var database = clientMongoDB.GetDatabase("Amministrazione");
        //Rilevo il numero dei documenti di una collection
        var collection = database.GetCollection<BsonDocument>("Dati");
        Int64 totaleDocumenti = collection.CountDocuments(new BsonDocument());
        MessageBox.Show($"Totale Documenti: {totaleDocumenti}");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Possiamo utilizzare anche una classe anziché quella generale di MongoDB.
Di seguito si riporta una classe che mappa la collection presente nel database, dove le proprietà hanno lo stesso nome dei campi della collection.

C#
   public class Dati
   {
       public ObjectId _id { get; set; }
       public string nome { get; set; }
       public string cognome { get; set; }
       public string email { get; set; }
       public DateTime data_nascita { get; set; }
   }

Di seguito si riporta l’utilizzo della classe che viene passato al metodo “GetCollection”  per rilevare il numero dei documenti, con una classe. 

C#
private void BtnNumeroDocumenti_Click(object sender, EventArgs e)
{
   try
   {
       //Oggetto del client MongoDB
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       //Seleziono il database dal quale rilevare le collection
       var database = clientMongoDB.GetDatabase("Amministrazione");
       //Rilevo il numero dei documenti di una collection
       var collection = database.GetCollection<Dati>("Dati");
       Int64 totaleDocumenti = collection.CountDocuments(new BsonDocument());
       MessageBox.Show($"Totale Documenti: {totaleDocumenti}");
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Nel caso desideriamo sapere il numero dei documenti  in base ad uno filtro, possiamo effettuare una ricerca di determinati documenti, tramite la proprietà “Filter” ed il metodo “Eq”.
Di seguito si riporta il frammento di codice che fornisce il numero dei documenti, che hanno il campo “nome”, impostato con il valore “Luigi”.

C#
private void BtnNumeroDocumentiFiltro_Click(object sender, EventArgs e)
{
    try
    {
        //Oggetto del client MongoDB
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        //Seleziono il database dal quale rilevare le collection
        var database = clientMongoDB.GetDatabase("Amministrazione");
        //Seleziono la collection nella quale contare i documenti in base ad un filtro
        var collection = database.GetCollection<BsonDocument>("Dati");
        //Filtro per contare i documenti 
        var filtro = Builders<BsonDocument>.Filter.Eq("nome", "Luigi");
        Int64 totaleDocumenti = collection.CountDocuments(filtro);
        MessageBox.Show($"Totale Documenti: {totaleDocumenti}");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Lo stesso risultato possiamo ottenerlo anche utilizzando una classe, in questo caso, utilizzeremo la classe “Dati” vista in precedenza.
Di seguito il frammento di codice, con il filtro del documento tramite classe e la visualizzazione del numero dei documenti per quel tipo di filtro.

C#
       private void BtnNumeroDocumentiFiltro_Click(object sender, EventArgs e)
       {
           try
           {
               //Oggetto del client MongoDB
               var clientMongoDB = new MongoClient("mongodb://localhost:27017");
               //Seleziono il database dal quale rilevare le collection
               var database = clientMongoDB.GetDatabase("Amministrazione");
               //Seleziono la collection nella quale contare i documenti in base ad un filtro
               var collection = database.GetCollection<Dati>("Dati");
               //Filtro per contare i documenti 
               var filtro = Builders<Dati>.Filter.Eq("nome", "Luigi");
               Int64 totaleDocumenti = collection.CountDocuments(filtro);
               MessageBox.Show($"Totale Documenti: {totaleDocumenti}");
            }
           catch (Exception ex)
           {
               MessageBox.Show(ex.Message);
           }
       }

Creazione della collection


In questa parte vedremo come creare una collection, fornendo alcuni aspetti basilari e le varie tecniche che si possono utilizzare.
Le collection, sono i contenitori dei documenti, sono paragonate alle tabelle nei database relazionali.
Da un pulsante nella form, oppure da altra funzione o evento, richiameremo il metodo “CreateCollection” della classe “IMongoDatabase”, che permette la creazione delle collection.


Di seguito si riporta il frammento di codice della creazione di una collection.

C#
private void BtnCreaCollection_Click(object sender, EventArgs e)
{
    try
    {
        //Oggetto del client MongoDB
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        //Seleziono il database dal quale rilevare le collection
        var database = clientMongoDB.GetDatabase("Amministrazione");
        //Creo la collection
        database.CreateCollection("test");
    }
    catch (MongoCommandException ex)
    {
        MessageBox.Show(ex.Message);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Come si è visto dal precedente codice, il metodo accetta un parametro di tipo string, il nome della collection che si vuole creare.

Per verificare che la Collection esiste, per evitare errori o altro, possiamo effettuare una ricerca se il nome della collection non è già presente.
Di seguito si riporta il codice che verifica l’esistenza della collection, ed in caso di esito negativo la crea.

C#
private void BtnCreaCollection_Click(object sender, EventArgs e)
{
    try
    {
        //Oggetto del client MongoDB
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        //Seleziono il database dal quale rilevare le collection
        var database = clientMongoDB.GetDatabase("Amministrazione");
        if (!database.ListCollectionNames().ToList().Contains("test"))
        {
            //Creo la collection
            database.CreateCollection("test");
        }
        else
        {
            MessageBox.Show("Collection già presente");
        }
    }
    catch (MongoCommandException ex)
    {
        MessageBox.Show(ex.Message);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Nella creazione delle Collection, possiamo impostare delle opzioni, in questo caso dobbiamo verificare se la collection esiste oppure no, perché nell’impostare i parametri come i limiti di documento e grandezza, se la collection esiste, verrà generata un’eccezione.
In questo esempio di codice nel linguaggio di programmazione C#, vediamo come creare una collection impostando una dimensione massima di 1 mb ed un solo documento.

C#
private void BtnCreaCollection_Click(object sender, EventArgs e)
{
   try
   {
       //Oggetto del client MongoDB
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       //Seleziono il database dal quale rilevare le collection
       var database = clientMongoDB.GetDatabase("Amministrazione");
       if (!database.ListCollectionNames().ToList().Contains("test5"))
       {
           var opzioni = new CreateCollectionOptions
           {
               Capped = true, //Abilito che una volta superato il limite ricomincia eliminando i documenti più vecchi Mantiene i limiti impostati
               MaxSize = 1000000, //dimensione massima della collection (1 mb) 
               MaxDocuments = 1   //Un solo documento può contenere
           };
           //Creo la collection
           database.CreateCollection("test5", opzioni);
       }
       else
       {
           MessageBox.Show("Collection già presente");
       }
   }
   catch (MongoCommandException ex)
   {
       MessageBox.Show(ex.Message);
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Nel precedente esempio di codice, qualora esiste già un documento, quello meno recente verrà eliminato per l'inserimento del nuovo documento.

Le collection si possono creare anche in maniera automatica, inserendo un nuovo documento.
In questo esempio verrà creata la collection denominata “Dati2”, la quale collection non dev'essere presente nel database. La creazione avviene utilizzando la classe Dati,  inserendo un nuovo documento.

C#
private void BtnCreaCollectionInsertOne_Click(object sender, EventArgs e)
{
   try
   {
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       var database = clientMongoDB.GetDatabase("Amministrazione");
       var collection = database.GetCollection<Dati>("Dati2");
       // Crea un nuovo oggetto Dati
       var nuovoDato = new Dati
       {
           nome = "Emanuele",
           cognome = "Mattei",
           email = "emanuele@dominio.it"
       };
       // Inserisce il nuovo oggetto nella collection che quest'ultima verrà creat
       collection.InsertOne(nuovoDato);
   }
   catch (MongoCommandException ex) 
   {
       MessageBox.Show(ex.Message);
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Altra modalità per la creazione creazione di una collection, è quella di specificare le informazioni per i vari campi, in particolare il tipo e se sono obbligatori.
In questo esempio di codice, viene creata una collection con tre campi, due di tipo testo ed uno di tipo numerico, tutti e tre i campi sono obbligatori.

C#
 private void BtnCreaCollectionCampiObbligatori_Click(object sender, EventArgs e)
 {
     try
     {
         //Oggetto del client MongoDB
         var clientMongoDB = new MongoClient("mongodb://localhost:27017");
         //Seleziono il database dal quale rilevare le collection
         var database = clientMongoDB.GetDatabase("Amministrazione");
         if (!database.ListCollectionNames().ToList().Contains("Dati3"))
         {
             //Imposto un validatore, ossia la tipologia dei campi
             var validator = new BsonDocument {
                 {
                     "$jsonSchema", new BsonDocument { { "bsonType", "object" },
                     { "required", new BsonArray {"Nome", "Cognome", "Eta" } },
                     {  "properties", new BsonDocument { { "Nome", new BsonDocument { {"bsonType", "string" } } },
                     {  "Cognome", new BsonDocument { { "bsonType", "string" } } },
                     {  "Eta", new BsonDocument { {"bsonType", "int" } } }
                     }
                    }
                  }
                 }
                 };
             var opzioni = new CreateCollectionOptions<Dati>
             {
                 Validator = validator
             };
             //Creo la collection
             database.CreateCollection("Dati3", opzioni);
         }
         else
         {
             MessageBox.Show("Collection già presente");
         }
     }
     catch (MongoCommandException ex)
     {
         MessageBox.Show(ex.Message);
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }

La cancellazione delle collection


In questa nuova parte vedremo come cancellare una collection esistente, con tutto il suo contenuto.
In questi casi occorre fare molta attenzione, perché la cancellazione di una collection, comporta la perdinta dei documenti ed altre informazioni che possono tornare utile.
In questo frammento codice utilizzeremo una collection creata appositamente per una dimostrazione di eliminazione.
La cancellazione avviene tramite il metodo “DropCollection”.
Di seguito si riporta il frammento di codice per la cancellazione di una collection con tutto il suo contenuto.

C#
private void BtnEliminaCollection_Click(object sender, EventArgs e)
{
    try
    {
        //Oggetto del client MongoDB
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        //Seleziono il database dal quale rilevare le collection
        var database = clientMongoDB.GetDatabase("Amministrazione");
        //Cancello la collection
        database.DropCollection("test2");
    }
    catch (MongoCommandException ex)
    {
        MessageBox.Show(ex.Message);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Rinomina di una collection


Tramite il metodo “RenameCollection” della classe “IMongoDatabase”, possiamo rinominare una collection esistente. Questo metodo potrebbe generare eccezioni, in alcuni casi, in particolare quando la collection che si vuole rinominare non è presente nel database, oppure nel caso che si sta rinominando una collection esistente in un’altra che è già presente. Il metodo richiede due parametri di tipo testo, il primo, il nome della collection che dev’essere rinominata e quindi esistente nel database, nel secondo parametro il nome della nuova collection che non dev’essere presente.
Il frammento di codice qui di seguito, verifica se la collection da rinominare è presente, e se il nuovo nome della collection che si vuole attribuire non è presente.
Di seguito si riporta il frammento di codice della rinomina di una collection con la verifica.

C#
private void BtnRinominaCollection_Click(object sender, EventArgs e)
{
   try
   {
       //Oggetto del client MongoDB
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       //Seleziono il database dal quale rilevare le collection
       var database = clientMongoDB.GetDatabase("Amministrazione");
       //Verifico che la prima collection esiste e che la seconda non è presente
       if (database.ListCollectionNames().ToList().Contains("test3") && !database.ListCollectionNames().ToList().Contains("test4"))
       {
           database.RenameCollection("test3", "test4");
       }
   }
   catch (MongoCommandException ex)
   {
       MessageBox.Show(ex.Message);
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Conclusioni


Questa serie di esempi di codice nel linguaggio C#, hanno illustrato al lettore alcuni aspetti sulla gestione delle collection. L’articolo ha voluto fornire una panoramica sull’utilizzo delle Collection, utilizzando la tecnologia .Net versione 9 ed il linguaggio di programmazione c#. La semplicità di questo database NoSql permette di scrivere codice e realizzare applicazioni in maniera rapida e facile, permettendo di abbattere tempi e costi nella gestione dei dati.