1. 程式人生 > >MondoDB介紹 Python與MongoDB用法,安裝PyMongo

MondoDB介紹 Python與MongoDB用法,安裝PyMongo

MongoDB

    將幾個月的成果總結成一篇文章,總結了一些大神相關MongoDB的資料和本人相關技術的應用案例,經驗 ,希望可以幫到你能夠更好的瞭解MogoDB,廢話不多說,下面開始

簡要介紹mongodb 

MongoDB是一個基於分散式檔案儲存的資料庫。 MongoDB 是一個跨平臺的,面向文件的資料庫,提供高效能,高可用性和可擴充套件性方便,是一個介於關係資料庫和非關係資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係資料庫的。他支援的資料結構非常鬆散,是類似json的bjson格式,因此可以儲存比較複雜的資料型別。Mongo最大的特點是他支援的查詢語言非常強大,其語法有點類似於面向物件的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能。mongodb中有三元素:資料庫,集合,文件,其中“集合”就是對應關係資料庫中的“表”,“文件”對應“行”。



功能:



* 面向集合的儲存:適合儲存物件及JSON形式的資料。
* 動態查詢:Mongo支援豐富的查詢表示式。查詢指令使用JSON形式的標記,可輕易查詢文件中內嵌的物件及陣列。
* 完整的索引支援:包括文件內嵌物件及陣列。Mongo的查詢優化器會分析查詢表示式,並生成一個高效的查詢計劃。
* 查詢監視:Mongo包含一個監視工具用於分析資料庫操作的效能。
* 複製及自動故障轉移:Mongo資料庫支援伺服器之間的資料複製,支援主-從模式及伺服器之間的相互複製。複製的主要目標是提供冗餘及自動故障轉移。
* 高效的傳統儲存方式:支援二進位制資料及大型物件(如照片或圖片)
* 自動分片以支援雲級別的伸縮性:自動分片功能支援水平的資料庫叢集,可動態新增額外的機器。


下載安裝和配置 



解壓mongodb-win32-x86_64-2.6.6.zip ,建立路徑C:\mongodb ,將解壓後的Bin檔案Copy to 此資料夾下
C:\mongodb 下建立Data資料夾 C:\mongodb\data ,然後分別建立db,log兩個資料夾,至此mongodb下有以下資料夾
在log資料夾下建立一個日誌檔案MongoDB.log,即C:\mongodb\data\log\MongoDB.log
程式啟動方式:
執行cmd.exe 進入DOS命中介面

>cd C:\mongodb\bin
>C:\mongodb\bin>mongod -dbpath "C:\mongodb\data\db"


執行此命令即將mongodb的資料庫檔案建立到C:\mongodb\data\db 目錄,會看到命令最後一行sucess的成功提示,此時資料庫就已啟動,該介面為Mongo的啟動程式,關閉後可直接雙擊bin下的mongod.exe,啟動程式開啟後,再執行mongo.exe

將MongoDB安裝為windows服務:

執行cmd.exe
> cd C:\mongodb\bin
> C:\mongodb\bin>mongod --dbpath "C:\mongodb\data\db" --logpath "C:\mongodb\data\log\MongoDB.log" --install --serviceName "MongoDB"

這裡MongoDB.log就是開始建立的日誌檔案,--serviceName "MongoDB" 服務名為MongoDB

>NET START MongoDB   (開啟服務)
>NET stop MongoDB   (關閉服務)


安裝完畢!!!奮鬥


MongoDB認證 

步驟分解 

1.MongoDB安裝時不新增任何引數,預設是沒有許可權驗證的,登入的使用者可以對資料庫任意操作而且可以遠端訪問資料庫,需以--auth引數啟動。
1.在剛安裝完畢的時候MongoDB都預設有一個admin資料庫,此時admin資料庫是空的,沒有記錄許可權相關的資訊。當admin.system.users一個使用者都沒有時,即使mongod啟動時添加了--auth引數,如果沒有在admin資料庫中新增使用者,此時不進行任何認證還是可以做任何操作(不管是否是以--auth 引數         啟動),直到在admin.system.users中添加了一個使用者。
1.MongoDB的訪問分為連線和許可權驗證,即使以--auth引數啟動還是可以不使用使用者名稱連線資料庫,但是不會有任何的許可權進行任何操作
1.admin資料庫中的使用者名稱可以管理所有資料庫,其他資料庫中的使用者只能管理其所在的資料庫。
1.在2.4之前版本中,使用者的許可權分為只讀和擁有所有許可權;2.4版本的許可權管理主要分為:資料庫的操作許可權、資料庫使用者的管理許可權、叢集的管理許可權,建議由超級使用者在admin資料庫中管理這些使用者。不過依然相容2.4版本之前的使用者管理方法。

 使用者操作

認證 

db.auth("user","password")


全部使用者 

show users // db.system.users.find() 


// 超級使用者 root

db.createUser({user: "root",pwd: "123456",roles: [ "root" ]})


// 修改密碼

 db.changeUserPassword("root", "root")



// 刪除原使用者 

db.dropUser("test") // db.system.users.remove({user:"test"});


MongoDB索引 



索引的優點


1.不需要做全表掃描,只需要掃描索引索引只儲存了這個表的資料的一小部分,這小部分可以幫我們實現快速查詢,因此掃描的時候只掃描這一小部分即可,如果將這小部分裝載入記憶體中的話,速度會更快
2.大大減少了伺服器需要掃描的資料量
3.索引可以幫助伺服器避免排序或使用臨時表
4.索引可以將隨機I/O轉換為順序I/O


 
索引的缺點 


1. 索引是儲存了資料表上的一小部分資料,那麼這些資料是需要額外儲存的,毫無疑問如果更新了表中的資料,那麼響應的索引資料也要跟著更新,加速了查詢操作,但是減少了寫入速度對查詢的加速是否有用還是有待評估的,比如我們將一個表中的按年齡實現了索引建立(在年齡上建立了索引)平時大多數操作都是按照名字上去查詢的,那麼索引則無任何作用,所謂索引必須跟查詢建完全匹配才有意義,但我們要知道大多數的查詢未必只在有限欄位上執行,也就意味著建立索引必須包含多個段,需要看索引是如何去生成的,對於多個條件可以將索引做為組合索引來查詢,所以索引的設計是非常有技巧的
2. 索引本身帶來的未必是優勢,如果一張表中索引非常的多的話,可能對於整個系統性能的影響是非常大的,如果一張表的本身非常小隻有十幾行,建立索引反而會減慢速度的,因為全表掃描也未必用不了多長時間
3. 但如果表非常大的話,索引則非常有用,如果資料量過大那麼索引反而也未必有意義,比如一張表非常大,上T的資料,可以想象一下建立什麼樣的索引才可以,所以只能將大表切割成小表,並且分佈在不同的物理節點上,對mysql來說叫做分割槽;對mongodb來講叫shaerd


索引型別


1. 單鍵索引(建立在一個欄位上的索引)
2. 組合索引(上面提到了)
3. 多鍵索引(一個文件中某個欄位的值可以是陣列,如果建立在這麼個欄位上,一個欄位上有多個值,則為多鍵索引,(一個值為一個數組))
4. 空間索引(只能使用空間索引函式,與mysql一致)
5. 文字索引(全文索引)
6. 雜湊索引


 操作 
使用ensureIndex來建立索引,1為升序,-1為倒序
> db.foo.ensureIndex({“x”:1, “y”:-1})

tip:查詢要返回集合中一半以上的結果,反而沒有必要建立索引,直接一條條掃描資料會高效一些

建立唯一索引
> db.test.ensureIndex({“x”:1}, {“unique”:true})



建立唯一索引前可能會有重複資料,我們可以使用”dropDups”來魯莽的刪除這些重複資料,寫法如下
> db.test.ensureIndex({“x”:1}, {“unique”:true, “dropDups”:true})



當然,最好還是寫個指令碼預處理好這些資料在建立唯一索引是更好的解決方法


我們可以在建立索引時,為索引起個名字,而不是用系統自動生成的名字
> db.test.ensureIndex({“x”:1}, {“name”: “myindex”})


當我們的集合資料量很大的時候,建立索引是一件費時費力的事情,我們可以這些寫建立索引的語句,是建立索引的過程在後臺完成:
> db.test.ensureIndex({“x”:1}, {“background”:true})



當索引不再使用的使用我們可以用dropIndexes來刪除索引
> db.runCommand({“dropIndexes”: “test”, “index”: “myindex”})



資料庫常用命令


* 切換/建立資料庫
   use yourDB;  當建立一個集合(table)的時候會自動建立當前資料庫
* 查詢所有資料庫
   show dbs;
* 刪除當前使用資料庫
   db.dropDatabase();
* 從指定主機上克隆資料庫
   db.cloneDatabase(“127.0.0.1”); 將指定機器上的資料庫的資料克隆到當前資料庫
* 從指定的機器上覆制指定資料庫資料到某個資料庫
   db.copyDatabase("mydb", "temp", "127.0.0.1");將本機的mydb的資料複製到temp資料庫中
* 修復當前資料庫
   db.repairDatabase();
* 檢視當前使用的資料庫
   db.getName();
* 顯示當前db狀態
   db.stats();
* 當前db版本
   db.version();
* 檢視當前db的連結機器地址
   db.getMongo();
* 建立一個聚集集合(table)
  db.createCollection(“collName”, {size: 20, capped: 5, max: 100});
* 得到指定名稱的聚集集合(table)
  db.getCollection("account");
* 得到當前db的所有聚集集合
  db.getCollectionNames();
* 顯示當前db所有聚集索引的狀態
  db.printCollectionStats();


用Python操作MongoDB需要通過PyMongo,下面就介紹一下PyMongo

PyMongo是Mongodb的Python介面開發包,是使用Python和Mongodb的推薦方式。本文將對PyMongo的使用進行介紹。

安裝 
  PyMongo包含在PythonPackage Index中https://pypi.python.org/pypi/pymongo/

  PyMongo的安裝不需要依賴其他包,但可以通過其他包來擴充套件應用(參見參考連結)。

其安裝方式包括一下幾種:

  * 使用pip安裝:
pip install pymongo          預設安裝
pip install pymongo==2.8      安裝指定版本
pip install –upgrade pymongo   升級PyMongo

  * 使用easy_install安裝:
easy_install pymongo
easy_install –U pymongo 

  * 使用原始檔進行安裝
git clonegit://github.com/mongodb/mongo-python-driver.git pymongo
cd pymongo/
pythonsetup.py install

使用簡介


* 使用條件
      在使用前需要保證PyMongo安裝成功,並且Mongodb已經啟動,且下圖命令執行成功無報錯:   

      `>>> import pymongo`

* 建立與MongoClient連線
     連線預設host和port   
     `>>> from pymongo import MongoClient>>> client = MongoClient()`

     連線指定host和port   
     `>>> client = MongoClient('localhost', 27017)`


* 獲取資料庫 Database
     一個Mongodb例項可以支援多個獨立的databases。可以通過以下方式獲得資料庫:   
     `>>> db = client.test_database`

     如果資料庫名使用屬性風格無法通過上述方式獲取,可以使用字典風格(dictionary)獲取:   
     `>>> db = client['test-database']`


* 獲取集合(collection)
    集合是一組文件,Mongodb中的文件類似於關係資料庫中的行,而集合如同表。獲取Mongodb集合的方式與獲得database的方式相同:    
    `>>> collection = db.test_collection或>>> collection = db['test-collection']`


* 文件(documents)操作
     1. MongoDB中的資料以JSON格式儲存和表示。在PyMongo中,我們使用字典(dictionaries)來表示文件。作為示例,下面的字典為某blog的POST請求:    

     >>> import datetime>>> post = {"author": "Mike",
                                    "text": "My first blog post!", 
                                    "tags": ["mongodb", "python", "pymongo"],
                                    "date": datetime.datetime.utcnow()}`

        文件中可以包含原生Python型別(如datetime.dateime),這些會被自動轉換至/自相應的BSON型別。
     2. 插入文件
        Insert_one() 方法可以將一個文件插入一個集合:
        >>> posts = db.posts>>> post_id = posts.insert_one(post).inserted_id>>> post_idObjectId('...')

        文件中如果不包含id欄位時,其文件的’_id’欄位會自動插入,且該欄位需唯一。函式返回InsertOneResult的例項。
        當有文件插入後,server才會生成非空的集合posts,我們可以通過列出資料庫中所有的集合來驗證: 
        >>> db.collection_names(include_system_collections=False)[u'posts']


     3. 批量插入(insert_many)
        insert_many()函式可以接受list格式的引數作為第一引數,進行批量插入操作。該函式會將list中每一個文件都插入資料庫中,例項如下:

        >>> 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)}]
        >>> result= posts.insert_many(new_posts)
        >>> result.inserted_ids
        [ObjectId('...'), ObjectId('...')]



     4. 同時查詢多個文件
        find()函式可以用來查詢返回多個滿足條件的文件。find()函式的返回結果為cursor(遊標)物件例項,我們可以通過它來遍歷整個匹配結果文件。下例返回了我們之前插入到posts集合中的所有文件:

        >>> for postin posts.find():



     5. 查詢返回結果數目
        查詢集合內文件數目:

        >>> posts.count()

        查詢集合內滿足查詢條件的文件數目

        >>> posts.find({"author":"Mike"}).count()



Python操作MongoDB案例 



#!python
# -*- coding:utf-8 -*-

import sys,json
from pymongo import MongoClient
from pymongo import ASCENDING, DESCENDING
sys.path.append("..")
import uuid,time
from core.logger import mLogger


class MongoAdapter(NoSQLBase):
"""MongoDB資料庫的介面類"""
def __init__(self,pconf):
super(MongoAdapter, self).__init__()
self.conf = pconf
self.client = MongoClient(‘10.11.115.74’'27017')
self.db = self.client['default_db']


def save(self,data):
sucSaves = 0
try:
myCol = self.db[‘colName’]
myCol.save({"data":“data”, "datastore_timestamp": time.time()}) 
#self.db.ensure_index(sid, unique=False)#以ID建立索引
except Exception, e:
mLogger.error(e)


if sucSaves > 0:
return True
else:
return False