Pierwsze zabawy z MongoDb

Już od dłuższego czas chciałem poznać jedną z baz NoSql-owych. Niestety zawsze jak się zabierałem za poznawanie jakiejś miałem nad głową termin skończenia projektu i wolałem zrobić coś szybko w znanych mi już relacyjnych bazach danych. Teraz zacząłem projekt, którego zakończenie przewiduje na marzec, więc mam jeszcze trochę czasu żeby pobawić się czymś nowy. Jedną z nowości, które zamierzam lepiej poznać to darmowa, NoSql-owa baza danych MongoDB. Jest to baza dokumentowa, więc wszystkie dane przechowuje w postaci plików json. Podejście to projektowania danych jest trochę inne niż w bazach takich jak MS SQL Server, ponieważ nie ma tutaj relacji. Oczywiście można sobie zamodelować przechowywanie kluczy, ale lepiej jest trzymać wszystko w jednym dokumencie.

Czego potrzebujemy żeby zacząć przygodę z MongoDB?

Przede wszystkim musimy pobrać bazę ze storny producenta (http://www.mongodb.org/downloads). Następnie rozpakowujemy pobrane archiwum i właściwie już możemy odpalić bazę. Aby to zrobić uruchamiamy konsole (cmd/powershell), wchodzimy do katalogu bin i piszemy:

.mongod.exe -dbpath sciezka_do_katalogu_z_danymi

Nie zamykamy konsoli, gdyż spowoduje to zamknięcie bazy. Domyślnie nasza baza zostanie uruchomiona na 127.0.0.1:27017. Niestety nie możemy uruchomić żadnego panelu admina ani nic co pomoże nam zarządzać bazą poprzez przeglądarkę. Do tych celów polecam program Robomongo. Dzięki niemu będziemy mogli podejrzeć dane, dodać, aktualizować czy wywoływać własne skrypty.

 

Czas połączyć to z .NET-em

MongoDB świetnie integruje się z .NET-em. Cała dokumentacja jak zrobić bardziej zaawansowane rzeczy znajdziecie na stronie http://docs.mongodb.org/ecosystem/drivers/csharp/ Przede wszystkim warto przeczytać CSharp Driver LINQ Tutorial, żeby zobaczyć jak używać LINQ do wyciągania danych z bazy.

Do używania mongo potrzebne są dwie biblioteki: MongoDB.Bson.dll oraz MongoDB.Driver.dll, obie można zainstalować poprzez Package Manager z lini poleceń:

PM> Install-Package mongocsharpdriver

lub poprzez wizualny manager NuGet’a (Official MongoDB C# Driver). Tyle wystarczy żeby móc już używać mongoDB w swoim projekcie.

Jako bonus dołączam moją implementację wzorca Repository skierowanego specjalnie dla MongoDB. Klasa ta posiada, kilka moich zdaniem kluczowych funkcjonalności takich jak:

  • zwraca nie cała listę obiektów, a obiekt IQueryable, który pozwala na tworzenie kwerend LINQ,
  • zwraca obiekt po jego Id,
  • przy dodawaniu nowego obiektu generuje mu nowe Id,
  • jeśli nie podamy nazwy kolekcji stworzy automatycznie kolekcje odpowiadającą nazwie typu obiektu, który zapisujemy w bazie.
/// <summary>
/// This class provides Id property
/// </summary>
public abstract class ModelBase
{
    public string Id { get; set; }
}

public class MongoRepository<T> 
    where T : ModelBase
{
    public MongoDatabase Database { get; private set; }

    private string _tableName;

    public MongoRepository(string tableName)
    {
        this._tableName = tableName;
        CreateDatabase();
    }

    public MongoRepository()
    {
        CreateDatabase();
    }

    private void CreateDatabase()
    {
        MongoClient client = new MongoClient();
        MongoServer server = client.GetServer();
        Database = server.GetDatabase("databasename");
    }

    public IQueryable<T> GetAll()
    {
        var col = GetTColection();
        return col.AsQueryable<T>();
    }

    public T GetById(string id)
    {
        var col = GetTColection();
        return col.AsQueryable<T>().Single(e => e.Id == id);
    }

    public void Add(T obj)
    {
        if (obj.Id == null )
        {
            obj.Id = ObjectId.GenerateNewId().ToString();
        }
        var col = GetTColection();
        col.Insert(obj);
    }

    public void Remove(string id)
    {
        var col = GetTColection();
        col.Remove(Query.EQ("_id", id));
    }

    public void Update(T obj)
    {
        var col = GetTColection();
        col.Save(obj);
    }

    private MongoCollection<T> GetTColection()
    {
        if (!string.IsNullOrEmpty(_tableName))
            return Database.GetCollection<T>(_tableName);
        else
            return Database.GetCollection<T>(typeof(T).Name);
    }
}

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

This site uses Akismet to reduce spam. Learn how your comment data is processed.