Mongodb python驅動教程
安裝
使用python驅動mongodb需要下載、安裝PyMongo包
- Windows用戶,點擊這里下載。
- 使用pip安裝在linux平臺使用pip命令安裝:
pip install pymongo指定版本:
pip install pymongo==2.6.3
升級:`pip install –upgrade pymongo
</li> - 使用easy_install安裝
easy_install pymongo
升級:easy_install -U pymongo
</ul>
使用
安裝完畢后,就可以在python shell或者python ide中進行試驗,如果安裝pymongo成功,那么下面的命令應該可以在python shell中運行:
>>> import pymongo
通過MongoClient連接mongo
#連接locahost上的mongodb,端口是默認端口,27017
from pymongo import MongoClient
client = MongoClient 也可以手動指定host和port:
client = MongoClient("localhost", 27017)
#或者
client = MongoClient("mongodb://localhost:27017/")</code></pre> <h3>獲取數據庫實例</h3>
一個mongodb的實例中,可以有很多獨立數據庫。我們可以通過下面的方式獲取一個數據庫的實例:
db = client.mydatabase
如果上面的方法不起作用,試一下下面的方法:
db = client['mydatabase']
獲取數據集
所謂數據集就是存儲再mongodb中的一堆文檔,這里可以簡單的理解成關系數據庫中的表(table),下面的方法獲取一個數據集:
collection = db.mycollection
#或者
collection = db[mycollection]</code></pre> <p>需要注意的是,不管是獲取數據庫、還是數據集實例,mongodb其實沒有進行任何操作,只有當真正的文檔insert進去的時候,才會真正創建數據庫和數據集。</p>
Documents
Mongodb中的數據是以json風格的文檔存在的。在PyMongo中,我們使用dictionaries代表documents。下面的一段文檔(dictionary),可以看作是一篇博文的簡介:
import datatime
post = {
"auther" : "Mike",
"text" : "My First blog post",
"tags" : ["mongodb", "python", "pymongo"],
"date" : datetime.datetime.utcnow()
}
Document可以包含python語句,如上面的datetime.datetime,執行時,會自動進行轉化。
插入Document
使用insert()方法進行插入:
posts = db.posts
post_id = posts.insert(post)
print post_id
當一篇Document被插入到mongodb中,如果document中沒有指定”_id”,mongodb會自動為該document添加唯一的”_id”。這個”_id”在該數據集中是惟一的。insert()方法返回值就是這個id,更多關于id的信息,點擊documentation on _id。
插入完成后,我們可以通過下面的語句列出數據庫中的數據集:
db.collection_names()
結果如下:
[u'system.indexs', u'posts']
system.indexs 這個數據集是mongodb自己創建的內部數據集。
使用find_one()方法獲取指定的Document
monbodb中find_one()方法,是最基本的查找方法。該方法返回符合條件的一篇document(如果沒有符合條件的,返回None)。當數據集中只有一篇符合條件的文檔,或者我們只想看第一篇文檔的時候,find_one()就有很有用了。
posts.find_one()
返回結果:
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
通過ObjectId檢索
我們也可以通過_id來進行檢索,在這里_id是ObjectId:
posts.find_one({"_id": post_id})
結果:
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
再web應用中,比較常見的就是通過url中的id,來查詢相應的document。通常傳過來的id是string類型的,我們需要將其轉化為ObjectId類型。
from bson.objectid import ObjectId
# web頁面中,將post_id字符串傳遞過來
def get(post_id):
# Convert from string to ObjectId:
document = client.db.collection.find_one({'_id': ObjectId(post_id)})</code></pre> <h3>關于Unicode字符串</h3>
你可能發現我們存到mongodb中的文檔,和我們查詢出來的文檔不太一樣(u’Mike’和‘Mike’)。
MongoDB以BSON的格式存儲數據。BSON格式的字符串是UTF-8編碼的,因此PyMongo必須保證它存儲的字符串都是utf-8編碼的。Regular strings (<type ‘str’>) are validated and stored unaltered. Unicode字符串首先被UTF-8編碼。PyMongo在輸出時使用u’Mike’代替’Mike’,就是PyMongo對每個BSON字符串進行解碼,解成python的unicode字符串。更多
批量Insert
如果要插入很多條數據,一條條插入就顯得很麻煩了。PyMongo支持批量插入。下面是例子:
new_posts = [
{ "author": "Mike",
"text": "Another post!",
"tags": ["bulk", "insert"],
"date": datetime.datetime(2009, 11, 12, 11, 14)},
{
"author": "Eliot",
"title": "MongoDB is fun",
"text": "and pretty easy too!",
"date": datetime.datetime(2009, 11, 10, 10, 45)
}]
posts.insert(new_posts)</code></pre> <p>結果會打印出兩個_id。</p>
例子總結:
+ 這個insert()方法返回兩個ObjectId對象,每個代表一個插入的Document。
- new_post[1] 沒有tags字段,增加了title字段,這樣做是OK的。這就是mongodb schema-free的體現。</p>
檢索多個Document
如果我們想同時檢索多條數據,需要用到find()方法。find()方法返回一個Cursor實例,我們可以這個Cursor來遍歷查詢到的Documents。如下面的例子:
for post in posts.find():
print post</code></pre> <p>類似結果如下:</p>
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']}
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'and pretty easy too!', u'_id': ObjectId('...'), u'author': u'Eliot', u'title': u'MongoDB is fun'}
為find()方法,添加約束條件:
for post in posts.find({"author": "Mike"}):
print post</code></pre> <p>類似結果:</p>
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']}
Counting
如果我們項查看某個條件下結果的個數,可以使用count()方法,這就省掉了全局檢索。
posts.count()
post.find({"author" : "Mike"}).count()
范圍檢索
Mongodb支持多種不同類型的高級查詢, 下面這個例子,檢索出某個時間點前發表的博文,并且按照作者名字排序:
d = datetime.datetime(2009, 11, 12, 12)
for post in posts.find({"date": {"$lt": d}}).sort("author"):
print post</code></pre> <p>結果如下:</p>
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'and pretty easy too!', u'_id': ObjectId('...'), u'author': u'Eliot', u'title': u'MongoDB is fun'}
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']}
索引
為了讓上面的那個查詢變得更快,我們可以在”date”和”author”字段上加上復合索引。
>>> from pymongo import ASCENDING, DESCENDING
>>> posts.create_index([("date", DESCENDING), ("author", ASCENDING)])
u'date_-1_author_1'
>>> posts.find({"date": {"$lt": d}}).sort("author").explain()["cursor"]
u'BtreeCursor date_-1_author_1'
>>> posts.find({"date": {"$lt": d}}).sort("author").explain()["nscanned"]
2
這種情況,查詢語句會使用BtreeCuosor(the index),查詢出了兩條結果。更多,點擊此處。