Pythontr

husonet | Tarih: 09.12.2014

pymongo nedir?

pymongo kurulumu ve notları

Pymongo kısaca mongodb sürücüsüdür. Mongodb ile bağlantı ve diğer nosql işlemlerimizi yapmamızı sağlar.



Pymongo Kurulumu

easy_install ile kurulumu aşağıdaki şekildedir.


easy_install pymongo

Upgrade için aşağıdaki işlem yapılmalıdır.


easy_install -U pymongo


Pymongo Git üzerinden kurulum işlemleri
git clone git://github.com/mongodb/mongo-python-driver.git pymongo
cd pymongo/
python setup.py install


Kurulum testi ipython ile yapılabilir.
import pymongo


MongoClient ile bağlantı kurulumu

PyMongo ile çalışan ilk adım bir MongoClient ve mongod örneği oluşturulması. Bunun için aşağıdaki kodları inceleyin.


from pymongo import MongoClient
client = MongoClient()

Yukarıdaki kod, varsayılan ana bilgisayar ve bağlantı noktası ile bağlanacaktır. Biz ayrıca ana bilgisayar ve bağlantı noktası belirtebiliriz, aşağıdaki gibi:


client = MongoClient('localhost', 27017)

Veya NoSQL URI biçimi kullanabiliriz


client = MongoClient('mongodb://localhost:27017/')


MongoDb database işlemleri
db = client.test_database

Öznitelik tarzı erişim kullanarak (test-veritabanı gibi) işe yaramaz öyle ki sizin veritabanı adı ise, bunun yerine sözlük dictionary stil erişim kullanabilirsiniz:


db = client['test-database']


MongoDb Collection işlemleri

Bir collection NoSQL içinde depolanan belgeleri grubudur, kabaca ilişkisel veritabanlarında tablo ile eşdeğer olarak düşünebilirsiniz.


collection = db.test_collection

dictionary olarak
collection = db['test-collection']

Not database ve collection lar çağırıldıklarında mevcut değil ise çağrıldıkları tanımlarla oluşuturulur.



Veri işlemleri

NoSQL verileri JSON stili belgelerini kullanırlar. PyMongo içinde belgeleri göstermek için sözlükler 'dictionaries' kullanılır. Örneğin, aşağıdaki sözlük bir blog yazısı temsil etmek için kullanılmıştır:


import datetime
post = {"yazar": "Hüseyin",
"text": "Benim ilk nosql içeriğim!",
"tags": ["mongodb", "python", "pymongo"],
"date": datetime.datetime.utcnow()}


Not belgeler otomatik olarak gelen uygun BSON türleri ve dönüştürülmüş yerel Python türleri (datetime.datetime gibi örnekler) içerebilir.



Ekleme 'İnsert' İşlemleri

Bir belgeyi bir collection a ekleme işlemi için insert() methodunu kullanabilirsiniz:


posts = db.posts
post_id = posts.insert(post)
post_id
Out: ObjectId('...')


Belge zaten bir "_id" anahtarı içermez, belgeye bir özel anahtar, "_id" otomatik olarak eklenir. "_id" değerini collection dan benzersiz olması gerekir. insert() eklenen belge için "_id" değerini döndürür.


İlk belgeyi ekledikten sonra collection, aslında sunucuda oluşturuldu. Biz bu bizim veritabanındaki derlemeleri listelendiğiniz zaman doğrulayabilirsiniz.


db.collection_names()
Out: [u'system.indexes', u'posts']

Not: System.indexes collectionu, otomatik olarak oluşturulan özel bir iç collection dur.


find_one() methodu ile tek bir kayda erişme

Bu fonksiyon eşleşme olursa tek bir belge döndürür.


posts.find_one()
Out: {u'date': datetime.datetime(...), u'text': u'Benim ilk nosql içeriğim!', u'_id': ObjectId('...'), u'yazar': u'Hüseyin', u'tags': [u'mongodb', u'python', u'pymongo']}

Not: Döndürülen belge "otomatik olarak ekle bağlanmış olan bir _id", içerir.


find_one() belirli öğeler üzerinde sorgulama destekler. "Hüseyin" ile 'yazar' anahtarları ile bir belge 'document' sonuçlarını sınırlayabiliriz.


posts.find_one({"yazar": "Hüseyin"})
Out: {u'date': datetime.datetime(...), u'text': u'Benim ilk nosql içeriğim!', u'_id': ObjectId('...'), u'yazar': u'Hüseyin', u'tags': [u'mongodb', u'python', u'pymongo']}

ObjectId üzerinden sorgulamalar
post_id
Out: ObjectId(...)
posts.find_one({"_id": post_id})
Out: {u'date': datetime.datetime(...), u'text': u'Benim ilk nosql içeriğim!', u'_id': ObjectId('...'), u'yazar': u'Hüseyin', u'tags': [u'mongodb', u'python', u'pymongo']}

Not: ObjectId ler string veri tipi ile sorgu döndürmez


post_id_as_str = str(post_id)
posts.find_one({"_id": post_id_as_str}) # sonuç dönmez

Web uygulamalarında ortak görev bulmak eşleşen belge ve ObjectId isteği URL'den elde edilir. Bu durumda ObjectId için find_one geçirmeden önce bir stringe dönüştürmek için gerekli olur:


from bson.objectid import ObjectId

# post_id URL'den alır ve bir string olarak geçer
def get(post_id):
# string veri ObjectId ye dönüştürülür
document = client.db.collection.find_one({'_id': ObjectId(post_id)})

Unicode stringler için bir not

MongoDb, BSON biçiminde veri depolar. BSON, UTF-8 olarak depolama işlemi yapar dolayısıyla tüm stringleri yalnızca geçerli UTF-8 veri içeren stringlerdir.


Toplu Ekleme İşlemleri

Sorgulamalarımızı daha etkili hale getirmek için belge 'document' daha fazla içerik ekleyelim. Tek bir belge ekleme işlemi yapmıştık, aşağıda şimdi birden fazla belgeyi aynı anda ekleme işlemini yapalım.


new_posts = [{"yazar": "Hüseyin",
"text": "ikinci post!",
"tags": ["bulk", "insert"],
"date": datetime.datetime(2009, 11, 12, 11, 14)},
{"yazar": "Serhan",
"title": "MogoDB Test",
"text": "İlk post denemesi",
"date": datetime.datetime(2009, 11, 10, 10, 45)}]
posts.insert(new_posts)
Out: [ObjectId('...'), ObjectId('...')]

Bu örnekte dikkat edilmesi gereken ilginç iki konu var



  • insert işlemi her eklenen bir belge için iki nesne kimliği örneği döndürdü.
  • new_posts verileri içinde birbirinde farklı anahtar kelimeler var mesala ikinci item da fazla olarak title var diğer mesajda yok, ilk itemda tags var diğerinde yok. Aslında bu hususu NoSql yapılarının avantajlarından biri olarak görebilirsiniz.

Birden fazla belge 'document' için sorgulama örnekleri


Bir sorgu sonucu olarak daha fazla tek bir belge almak için find() yöntemini kullanabiliriz. find() tüm eşleşen belgeler üzerinde yinelemek için bize izin verir bir imleç örneği döndürür. Örneğin, mesaj collection her belge üzerinde yineleme yapabilirsiniz:


for post in posts.find():
print post
Out: {u'yazar': u'H\xfcseyin', u'text': u'Benim ilk nosql i\xe7eri\u011fim!', u'_id': ObjectId('54870f36db661c31ebb1f42e'), u'date': datetime.datetime(2014, 12, 9, 15, 2, 58, 89000), u'tags': [u'mongodb', u'python', u'pymongo']}
{u'yazar': u'H\xfcseyin', u'text': u'ikinci post!', u'_id': ObjectId('54871319db661c31ebb1f42f'), u'date': datetime.datetime(2009, 11, 12, 11, 14), u'tags': [u'bulk', u'insert']}
{u'yazar': u'Serhan', u'text': u'\u0130lk post denemesi', u'_id': ObjectId('54871319db661c31ebb1f430'), u'date': datetime.datetime(2009, 11, 10, 10, 45), u'title': u'MogoDB Test'}

Tıpkı find_one gibi bu fonskiyon üzerinde de eşleştirme yapabilirsiniz.


for post in posts.find({"yazar": "Hüseyin"}):
print post

Out: {u'yazar': u'H\xfcseyin', u'text': u'Benim ilk nosql i\xe7eri\u011fim!', u'_id': ObjectId('54870f36db661c31ebb1f42e'), u'date': datetime.datetime(2014, 12, 9, 15, 2, 58, 89000), u'tags': [u'mongodb', u'python', u'pymongo']}
{u'yazar': u'H\xfcseyin', u'text': u'ikinci post!', u'_id': ObjectId('54871319db661c31ebb1f42f'), u'date': datetime.datetime(2009, 11, 12, 11, 14), u'tags': [u'bulk', u'insert']}

Countları alma işlemleri
posts.count()
3

Yada sadece eşleştirdiğimiz bir işlemimiz mevcut ise


posts.find({"yazar": "Hüseyin"}).count()
2

Aralıklı Sorgular

MongoDb birçok farklı türde gelişmiş sorgular yapabilirsiniz. Belirli tarihten itibaren yada belirli bir tarihten eski girdilerin çıktısını birde yazara göre sıralama yapabilecek ve sonuçları alabilecek bir örnek yazalım.


d = datetime.datetime(2009, 11, 12, 12)
for post in posts.find({"date": {"$lt": d}}).sort("yazar"):
print post
Out: {u'yazar': u'H\xfcseyin', u'text': u'ikinci post!', u'_id': ObjectId('54871319db661c31ebb1f42f'), u'date': datetime.datetime(2009, 11, 12, 11, 14), u'tags': [u'bulk', u'insert']}
{u'yazar': u'Serhan', u'text': u'\u0130lk post denemesi', u'_id': ObjectId('54871319db661c31ebb1f430'), u'date': datetime.datetime(2009, 11, 10, 10, 45), u'title': u'MogoDB Test'}

Burada Aralık sorgu yapmak ve ayrıca arama sonuçları yazara göre sıralamak için sort() özel "$lt" işlecini kullanılmıştır.


İndex işlemleri

Yukarıdaki sorgu işlemini daha hızlı hale getirmek için "Tarih" ve "Yazar" için bileşik index ekleyebiliriz.


posts.find({"date": {"$lt": d}}).sort("author").explain()["cursor"]

posts.find({"date": {"$lt": d}}).sort("yazar").explain()["cursor"]
Out: u'BasicCursor'

posts.find({"date": {"$lt": d}}).sort("yazar").explain()["nscanned"]
Out: 3

Birleşik index örneği
from pymongo import ASCENDING, DESCENDING

posts.create_index([("date", DESCENDING), ("yazar", ASCENDING)])
Out: u'date_-1_yazar_1'

posts.find({"date": {"$lt": d}}).sort("yazar").explain()["cursor"]
Out: u'BtreeCursor date_-1_yazar_1'

posts.find({"date": {"$lt": d}}).sort("yazar").explain()["nscanned"]
Out: 2


İlgili konular: MongoDb nedir