Uno sguardo a MongoDB

Introduzione

MongoDB è un database NoSQL che ha preso piede con l’avvento del nuovo web, in cui le prestazioni diventano fondamentali con l’aumento della richiesta utente che potrebbe venire da qualsiasi parte del globo.

Si tratta di un database orientato ai documenti, ossia agli oggetti anziché alle tabelle ed ha uno dei punti di forza nella flessibilità del modello dati, per il quale non è necessario definire a propri uno schema.

 

Preparazione

MongoDB è scaricabile nella versione 64 bit direttamente dal sito della MongoDB Inc. (https://www.mongodb.com/download-center#community).

Il pacchetto, oltre al motore DB, contiene anche il pannello di controllo denominato “MongoDB Compass”, con cui si può amministrare il server.

Il motore va installato come servizio Windows. Per fare ciò:

  1. Creare un file di configurazione “mongodb.cfg”, direttamente nella sottocartella bin in cui è stato installato MongoDB, dove definire le cartelle dati e log

 

  1. Creare fisicamente le cartelle definite nel file di configurazione

 

  1. Eseguire, in una finestra DOS con privilegi amministrativi direttamente dalla sottocartella bin, il file mongod.exe, avendo cura di specificare il percorso completo per il file di configurazione:
    mongod –config “C:\Program Files\MongoDB\Server\3.6\bin\mongodb.cfg” –install

 

  1. Definire le caratteristiche del servizio installato (es. partenza automatica o manuale) dal pannello di controllo servizi.

 

  1. Creare un DB di prova e una collection di prova direttamente col “MongoDB Compass”.

 

  1. Creare un progetto in Visual Studio ed installare il driver per MongoDB tramite la console NuGet, eseguendo il comando
    Install-Package MongoDB.Driver

 

Esempio di codice

Il codice di seguito riportato mostra come interagire con la collection, effettuando

  • Una SELECT con filtro
  • Un’UPDATE con condizioni di WHERE utilizzando valori correnti dei documenti estratti
  • Una INSERT

using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ProvaMongoDB
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(“Situazione iniziale…”);
            SelectAsync(20).Wait();

            UpdateAsync().Wait();
            Console.WriteLine(“\nDopo update…”);
            SelectAsync(20).Wait();

            Persona newPers = new Persona()
            {
                CibiPreferiti = new List<string> { “Insalata russa”, “Lasagne” },
                Eta = 35,
                IsMaschio = false,
                Nome = “Elena”
            };
            InsertAsync(newPers).Wait();
            Console.WriteLine(“\nDopo insert…”);
            SelectAsync(20).Wait();

            Console.ReadLine();
        }

        /// <summary>
        /// Estrae la collection delle Persone da MongoDB
        /// </summary>
        static IMongoCollection<Persona> GetPersoneFromMongoDb()
        {
            const string CONNECTION_STRING = “mongodb://localhost:27017”;
            const string DB_NAME = “Prova”;
            const string COLLECTION_NAME = “Documenti”;

            var client = new MongoClient(CONNECTION_STRING);
            var db = client.GetDatabase(DB_NAME);
            return db.GetCollection<Persona>(COLLECTION_NAME);
        }

        /// <summary>
        /// Estrae e stampa i record filtrati per età minima
        /// </summary>
        static async Task SelectAsync(int minEta)
        {
            IMongoCollection<Persona> collPers = Program.GetPersoneFromMongoDb();
            var persone = await collPers.Find<Persona>(p => p.Eta > minEta).ToListAsync();
            foreach (Persona p in persone)
                Console.WriteLine(“Persona: {0}\n”, p.ToBsonDocument());
         }

         /// <summary>
         /// Aumenta l’età di 1 per le persone femmine
         /// </summary>
         private static async Task UpdateAsync()
         {
             IMongoCollection<Persona> collPers = Program.GetPersoneFromMongoDb();
             var filter = Builders<Persona>.Filter.Eq(p => p.IsMaschio, false);
             using (var cursor = await collPers.FindAsync<Persona>(filter))
             {
                 //per ogni persona femmina…
                 await cursor.ForEachAsync(persona =>
                 {
                     //definisce cosa aggiornare
                     var update = Builders<Persona>.Update.Set(p => p.Eta, persona.Eta + 1);

                     //effettua l’aggiornamento
                     var result = collPers.UpdateOne<Persona>(p => p._id == persona._id, update);
                     Console.WriteLine(“N° record aggiornati: {0}”, result.ModifiedCount);
                 });
             }
         }

         /// <summary>
         /// Inserisce un elemento nella collection Documenti
         /// </summary>
         private static async Task InsertAsync(Persona newPers)
         {
             IMongoCollection<Persona> collPers = Program.GetPersoneFromMongoDb();
             await collPers.InsertOneAsync(newPers);
         }
     }

     /// <summary>
     /// Modello Dati
     /// </summary>
     class Persona
     {
         public ObjectId _id { get; set; }
         public string Nome { get; set; }
         public int Eta { get; set; }
         public bool IsMaschio { get; set; }
         public List<string> CibiPreferiti { get; set; }
     }
}

 

Conclusioni

Si tratta indubbiamente di una valida alternativa all’utilizzo di DB relazionali ma non in qualsiasi campo di applicazione. La velocità in lettura si ottiene rinunciando alla transazionalità e quindi alla consistenza del DB, quindi va benissimo per situazioni in cui si deve lavorare direttamente con dati aggregati ma il lavoro viene complicato quando è richiesto l’aggiornamento di dati che possono essere ridondati.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *