Zarządzanie danymi w bazie MongoDB

Opis interfejsu do zarządzania danymi w nierelacyjnej i wysoce skalowalnej bazie MongoDB

pymongo to sterownik dla bazy MongoDB. W tym artykule opiszę API tego modułu, oraz strukturę danych stosowaną w tej bazie danych. Nazewnictwo jest trochę inne. Mamy bazę danych, a w niej kolekcje - odpowiednik tabel w relacyjnej bazie danych. Kolekcje w odróżnieniu od tabel nie maja określonej struktury. W kolekcjach znajdują się dokumenty - odpowiednik wiersz, rekordów. Dokument to lista wartości klucz - wartość w formacie JSON (w przypadku modułu Pythona - słownik). Wartość klucza może zawierać zagnieżdżone słowniki (struktury JSON).

Serwer i baza danych

Instalujemy MongoDB z pakietów dostępnym w repozytorium dystrybucji lub pobieramy gotową binarną paczkę na stronie MongoDB, którą wystarczy rozpakować i gotowe. By uruchomić serwer wystarczy w konsoli wykonać:
mongod --dbpath=/ścieżka/do/katalogu
Podając ścieżkę do pustego katalogu na dane bazy danych. Instalujemy pymongo poprzez setuptools:
easy_install pymongo
Teraz możemy już operować na MongoDB z poziomu Pythona.

Podstawowe operacje na bazie danych

API jest proste w użyciu - łączymy się z serwerem, wybieramy bazę, wybieramy kolekcję i możemy na niej operować:
# -*- coding: utf-8 -*-

from pymongo import Connection

connection = Connection()
# test_db to nazwa bazy danych
db = connection.test_db
# first_collection to nazwa kolekcji
collection = db.first_collection

# ile dokumentów w kolekcji?
print collection.count()
Powyższy przykład stworzy bazę "test_db" jeżeli nie istnieje, a następnie wybierze kolekcję "first_collection" (stworzy jeżeli nie istnieje) i policzy ilość dokumentów w niej zawartych - oczywiście teraz nie będzie żadnego. Do dodawania dokumentów służy metoda insert przyjmująca słownik - dokument, lub listę słowników (lista dokumentów):
# -*- coding: utf-8 -*-

from pymongo import Connection
from pymongo import ASCENDING, DESCENDING

connection = Connection()
# test_db to nazwa bazy danych
db = connection.test_db
# first_collection to nazwa kolekcji
collection = db.first_collection

collection.insert({"title": "Tom", "age": 23})
collection.insert({"title": "Kate", "age": 21, "location": "UK", "phone": 1111111})
collection.insert([{"title": "Anna 1", "age": 33}, {"title": "Anna 2", "age": 34}])

print collection.count()
W powyższym przykładzie dodajemy cztery dokumenty. Jak widać ich struktura może być dowolna, nie muszą mieć tych samych kluczy. Po dodaniu dokumentu zyskuje on klucz _id o unikalnej wartości. Do pobierania dokumentów służy metoda find oraz find_one:
# -*- coding: utf-8 -*-

from pymongo import Connection
from pymongo import ASCENDING, DESCENDING

connection = Connection()
# test_db to nazwa bazy danych
db = connection.test_db
# first_collection to nazwa kolekcji
collection = db.first_collection

# pobieramy wszystkie dokumenty
docs = collection.find()
for i in docs:
    print i

# pobieramy jeden dokument
print
print collection.find_one({"title": "Anna 1"})
print

# pobieramy dokumenty z warunkami
docs = collection.find({"title": {'$exists': True}}).sort('_id', DESCENDING).skip(1).limit(2)
for i in docs:
    print i
Zarówno find jak i findone obsługują rozbudowany system argumentów do filtrowania wyników. Można stosować filtry po wartości danego pola, a także warunki większości, mniejszości, czy np. obecności danego klucza. Metoda skip pomija X pierwszych wpisów, a limit ogranicza ilość pobranych dokumentów. Metod sort pozwala sortować dokumenty po podanym kluczu rosnąco lub malejąco. Wcześniej zapisane dokumenty pobrane wyglądają tak:
{u'age': 23, u'_id': ObjectId('4b9bb0c5e1382315db000000'), u'title': u'Tom'}
{u'phone': 1111111, u'age': 21, u'_id': ObjectId('4b9bb0c5e1382315db000001'), u'location': u'UK', u'title': u'Kate'}
{u'age': 33, u'_id': ObjectId('4b9bb0c5e1382315db000002'), u'title': u'Anna 1'}
{u'age': 34, u'_id': ObjectId('4b9bb0c5e1382315db000003'), u'title': u'Anna 2'}
Do aktualizacji służy metoda update, która przyjmuje co najmniej dwa argumenty - słownik z warunkami określającymi dokumenty/dokument, oraz drugim słownikiem z danymi do modyfikacji:
# -*- coding: utf-8 -*-

from pymongo import Connection
from pymongo import ASCENDING, DESCENDING
from datetime import datetime

connection = Connection()
# test_db to nazwa bazy danych
db = connection.test_db
# first_collection to nazwa kolekcji
collection = db.first_collection

# aktualizacja dokumentu
collection.update({"title": "Anna 2"}, {"$set": {"date": datetime.utcnow()}})

print collection.find_one({"title": "Anna 2"})

W powyższym przykładzie aktualizujemy jeden dokument zmieniając wartość klucza "date". Dodatkowe argumenty tej metody to safe - jeżeli ustawimy na True to API upewni się czy operacja została wykonana, upsert - jeżeli True to stworzony zostanie dokument, jeżeli nie istnieje, multi - jeżeli True to operacja aktualizacji obejmie wszystkie pasujące dokumenty (a nie tylko jeden).

Sama baza może przechowywać pliki o rozmiarze do 4 MB. Większe pliki obsługiwane są bardzo efektywnie przez rozszerzenie GridFS (z obsługą replikacji plików).

Obiekt collection na którym operujemy posiada także inne metody odpowiedzialne m.in. za tworzenie, usuwanie indeksów, dokumentów itd. Wszystkie są ładnie udokumentowane. Polecam także wykład poświecony MongoDB i jej zaawansowanym opcjom.

blog comments powered by Disqus

Kategorie

Strony