1. 程式人生 > >MongoDB(一):Python-windows下mongodb安裝與使用整理

MongoDB(一):Python-windows下mongodb安裝與使用整理

序言:

本部落格通過六大方面介紹如下內容:

  • 前言介紹:介紹了包含MongoDB、NoSQL、關係型資料庫和非關係型資料的優缺點等內容。
  • Windows 平臺安裝MongoDB:介紹瞭如何在Windows下安裝MongoDB,學習python時可能會遇到安裝MongoDB,對於習慣了使用Windows的人有一定的幫助。
  • Python中安裝pymongo:供python爬蟲使用
  • 安裝mongoengine(通常django用此依賴操作mongodb)
  • MongoDB資料庫的使用:介紹了一些簡單的使用,查詢資料庫、增加、刪除、修改、查詢等命令的使用。
  • MongoDB高階應用:包含條件查詢、排序等內容的例項使用。

    其中二、Windows 平臺安裝MongoDB,三、Python中安裝pymongo,四、安裝mongoengine,

    這三步用於Python中使用MongoDB的操作。可以針對Python學習。

一、前言介紹

1、什麼是MongoDB ?

MongoDB 是由C++語言編寫的,是一個基於分散式檔案儲存的開源資料庫系統。

MongoDB是非關係型資料庫(NoSQL)。

在高負載的情況下,新增更多的節點,可以保證伺服器效能。

MongoDB 旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案。

MongoDB 將資料儲存為一個文件,資料結構由鍵值(key=>value)對組成。MongoDB 文件類似於 JSON 物件。欄位值可以包含其他文件,陣列及文件陣列。

2、什麼是NoSQL?

NoSQL,指的是非關係型的資料庫。NoSQL有時也稱作Not Only SQL的縮寫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱。

NoSQL用於超大規模資料的儲存。(例如谷歌或Facebook每天為他們的使用者收集萬億位元的資料)。這些型別的資料儲存不需要固定的模式,無需多餘操作就可以橫向擴充套件。

3、為什麼使用NoSQL ?

今天我們可以通過第三方平臺(如:Google,Facebook等)可以很容易的訪問和抓取資料。使用者的個人資訊,社交網路,地理位置,使用者生成的資料和使用者操作日誌已經成倍的增加。我們如果要對這些使用者資料進行挖掘,那SQL資料庫已經不適合這些應用了, NoSQL資料庫的發展也卻能很好的處理這些大的資料。

4、RDBMS vs NoSQL

RDBMS (關係型資料庫管理系統
- 高度組織化結構化資料 
- 結構化查詢語言(SQL) (SQL) 
- 資料和關係都儲存在單獨的表中。 
- 資料操縱語言,資料定義語言 
- 嚴格的一致性
- 基礎事務

NoSQL  (非關係型資料庫管理系統
- 代表著不僅僅是SQL
- 沒有宣告性查詢語言
- 沒有預定義的模式
-鍵 - 值對儲存,列儲存,文件儲存,圖形資料庫
- 最終一致性,而非ACID屬性
- 非結構化和不可預知的資料
- CAP定理 
- 高效能,高可用性和可伸縮性

5、關係型資料庫遵循ACID規則

事務在英文中是transaction,和現實世界中的交易很類似,它有如下四個特性:

5.1、A (Atomicity) 原子性

原子性很容易理解,也就是說事務裡的所有操作要麼全部做完,要麼都不做,事務成功的條件是事務裡的所有操作都成功,只要有一個操作失敗,整個事務就失敗,需要回滾。

比如銀行轉賬,從A賬戶轉100元至B賬戶,分為兩個步驟:1)從A賬戶取100元;2)存入100元至B賬戶。這兩步要麼一起完成,要麼一起不完成,如果只完成第一步,第二步失敗,錢會莫名其妙少了100元。

5.2、C (Consistency) 一致性

一致性也比較容易理解,也就是說資料庫要一直處於一致的狀態,事務的執行不會改變資料庫原本的一致性約束。

例如現有完整性約束a+b=10,如果一個事務改變了a,那麼必須得改變b,使得事務結束後依然滿足a+b=10,否則事務失敗。

5.3、I (Isolation) 獨立性

所謂的獨立性是指併發的事務之間不會互相影響,如果一個事務要訪問的資料正在被另外一個事務修改,只要另外一個事務未提交,它所訪問的資料就不受未提交事務的影響。

比如現在有個交易是從A賬戶轉100元至B賬戶,在這個交易還未完成的情況下,如果此時B查詢自己的賬戶,是看不到新增加的100元的。

5.4、D (Durability) 永續性

永續性是指一旦事務提交後,它所做的修改將會永久的儲存在資料庫上,即使出現宕機也不會丟失。

6、NoSQL的優點/缺點

優點:

  • - 高可擴充套件性
  • - 分散式計算
  • - 低成本
  • - 架構的靈活性,半結構化資料
  • - 沒有複雜的關係

缺點:

  • - 沒有標準化
  • - 有限的查詢功能(到目前為止)
  • - 最終一致是不直觀的程式

7、NoSQL 資料庫分類

二、Windows 平臺安裝MongoDB

1、MongoDB下載

你可以在mongodb官網下載該安裝包,地址為:https://www.mongodb.com/download-center#community。MonggoDB支援以下平臺:

  • OS X 32-bit
  • OS X 64-bit
  • Linux 32-bit
  • Linux 64-bit
  • Windows 32-bit
  • Windows 64-bit
  • Solaris i86pc
  • Solaris 64

2、建立資料目錄

MongoDB將資料目錄儲存在 db 目錄下。但是這個資料目錄不會主動建立,我們在安裝完成後需要建立它。

在本教程中,我已經在D盤安裝了 mongodb,現在讓我們建立一個 data 的目錄,然後在 data 目錄裡建立 db 目錄。

3、命令列下執行 MongoDB 伺服器

為了從命令提示符下執行 MongoDB 伺服器,你必須從 MongoDB 目錄的 bin 目錄中執行 mongod.exe 檔案。

即在D:\Program Files (x86)\MongoDB\bin目錄下開啟命令列,執行下面命令,配置db。

mongod.exe --dbpath "D:\Program Files (x86)\MongoDB\data\db"     //目錄中有空格要加雙引號在路徑上

如果執行成功,會輸出如下資訊:

2015-09-25T15:54:09.212+0800 I CONTROL  Hotfix KB2731284 or later update is not
installed, will zero-out data files
2015-09-25T15:54:09.229+0800 I JOURNAL  [initandlisten] journal dir=c:\data\db\j
ournal
2015-09-25T15:54:09.237+0800 I JOURNAL  [initandlisten] recover : no journal fil
es present, no recovery needed
2015-09-25T15:54:09.290+0800 I JOURNAL  [durability] Durability thread started
2015-09-25T15:54:09.294+0800 I CONTROL  [initandlisten] MongoDB starting : pid=2
488 port=27017 dbpath=c:\data\db 64-bit host=WIN-1VONBJOCE88
2015-09-25T15:54:09.296+0800 I CONTROL  [initandlisten] targetMinOS: Windows 7/W
indows Server 2008 R2
2015-09-25T15:54:09.298+0800 I CONTROL  [initandlisten] db version v3.0.6
……

4、連線MongoDB

我們可以在命令視窗中執行 mongo.exe 命令即可連線上 MongoDB,執行如下命令:

D:\Program Files (x86)\MongoDB\bin\mongo.exe    //即在bin目錄下開啟命令列 執行mongo.exe

5、配置 MongoDB 服務

管理員模式開啟命令列視窗

建立目錄,執行下面的語句來建立資料庫和日誌檔案的目錄

mkdir D:\Program Files (x86)\MongoDB\data\db         //建立db資料庫目錄
mkdir D:\Program Files (x86)\MongoDB\data\log        //建立log日誌檔案目錄

建立配置檔案

建立一個配置檔案。該檔案必須設定 systemLog.path 引數,包括一些附加的配置選項更好。

例如,建立一個配置檔案位於 D:\Program Files (x86)\MongoDB\mongod.cfg,其中指定 systemLog.path 和 storage.dbPath。

具體配置內容如下:

systemLog:
    destination: file
    path: D:\Program Files (x86)\MongoDB\data\log\MongoDB.log
storage:
    dbPath: D:\Program Files (x86)\MongoDB\data\db

6、安裝 MongoDB服務

通過執行mongod.exe,使用--install選項來安裝服務,使用--config選項來指定之前建立的配置檔案。

D:\Program Files (x86)\MongoDB\bin\mongod.exe --config "C:\mongodb\mongod.cfg" --install
//即在D:\Program Files (x86)\MongoDB\bin\目錄下執行下面命令
//mongod.exe --config "C:\mongodb\mongod.cfg" --install

要使用備用 dbpath,可以在配置檔案(例如:D:\Program Files (x86)\MongoDB\mongod.cfg)或命令列中通過 --dbpath 選項指定。

如果需要,您可以安裝 mongod.exe 或 mongos.exe 的多個例項的服務。只需要通過使用 --serviceName 和 --serviceDisplayName 指定不同的例項名。只有當存在足夠的系統資源和系統的設計需要這麼做。

啟動MongoDB服務

net start MongoDB

關閉MongoDB服務

net stop MongoDB

移除 MongoDB 服務

C:\mongodb\bin\mongod.exe --remove

7、MongoDB 後臺管理 Shell

如果你需要進入MongoDB後臺管理,你需要先開啟mongodb裝目錄的下的bin目錄,然後執行mongo.exe檔案,MongoDB Shell是MongoDB自帶的互動式Javascript shell,用來對MongoDB進行操作和管理的互動式環境。

當你進入mongoDB後臺後,它預設會連結到 test 文件(資料庫):

> mongo
MongoDB shell version: 3.0.6
connecting to: test
……

由於它是一個JavaScript shell,您可以執行一些簡單的算術運算:

> 2 + 2
4
>

db 命令用於檢視當前操作的文件(資料庫):

> db
test
>

插入一些簡單的記錄並查詢它:

> db.runoob.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.runoob.find()
{ "_id" : ObjectId("5604ff74a274a611b0c990aa"), "x" : 10 }
>

第一個命令將數字 10 插入到 runoob 集合的 x 欄位中。

三、Python中安裝pymongo

在安裝python的Scripts目錄下,執行下面命令:

//  pip安裝
$ python -m pip install pymongo
// easy_install安裝
$ python -m easy_install pymongo
// 下載git源安裝
$ python setup.py install

test_connection.py

>>> import pymongo
>>> client = pymongo.MongoClient("localhost", 27017)
>>> db = client.test
>>> db.name
u'test'
>>> db.my_collection
Collection(Database(MongoClient('localhost', 27017), u'test'), u'my_collection')
>>> db.my_collection.insert_one({"x": 10}).inserted_id
ObjectId('4aba15ebe23f6b53b0000000')
>>> db.my_collection.insert_one({"x": 8}).inserted_id
ObjectId('4aba160ee23f6b543e000000')
>>> db.my_collection.insert_one({"x": 11}).inserted_id
ObjectId('4aba160ee23f6b543e000002')
>>> db.my_collection.find_one()
{u'x': 10, u'_id': ObjectId('4aba15ebe23f6b53b0000000')}
>>> for item in db.my_collection.find():
...     print(item["x"])
...

四、安裝mongoengine(通常django用此依賴操作mongodb)

pymongo來操作MongoDB資料庫,但是直接把對於資料庫的操作程式碼都寫在指令碼中,這會讓應用的程式碼耦合性太強,而且不利於程式碼的優化管理

MongoEngine是一個物件文件對映器(ODM),相當於一個基於SQL的物件關係對映器(ORM)

MongoEngine提供的抽象是基於類的,建立的所有模型都是類

Examples

from mongoengine import *
connect('test')

class BlogPost(Document):
    title = StringField(required=True, max_length=200)
    posted = DateTimeField(default=datetime.datetime.utcnow)
    tags = ListField(StringField(max_length=50))
    meta = {'allow_inheritance': True}

class TextPost(BlogPost):
    content = StringField(required=True)

class LinkPost(BlogPost):
    url = StringField(required=True)

# Create a text-based post
>>> post1 = TextPost(title='Using MongoEngine', content='See the tutorial')
>>> post1.tags = ['mongodb', 'mongoengine']
>>> post1.save()

# Create a link-based post
>>> post2 = LinkPost(title='MongoEngine Docs', url='hmarr.com/mongoengine')
>>> post2.tags = ['mongoengine', 'documentation']
>>> post2.save()

五、MongoDB資料庫的使用

1. 常用的命令

  • show dbs    顯示資料庫列表
  • use dbname    進入dbname資料庫,大小寫敏感,沒有這個資料庫也不要緊
  • show collections    顯示資料庫中的集合,相當於表格

2. 建立&新增

  • db.users.save({"name":"lecaf"})    建立了名為users的集合,並新增了一條{"name":"lecaf"}的資料
  • db.users.insert({"name":"ghost", "age":10})    在users集合中插入一條新資料,,如果沒有users這個集合,mongodb會自動建立
  • save()和insert()也存在著些許區別:若新增的資料主鍵已經存在,insert()會不做操作並提示錯誤,而save() 則更改原來的內容為新內容。
    • 存在資料:{ _id : 1, " name " : " n1 "} ,_id是主鍵
    • insert({ _id : 1, " name " : " n2 " })    會提示錯誤
    • save({ _id : 1, " name " : " n2 " })     會把 n1 改為  n2 ,有update的作用。

3. 刪除

  • db.users.remove()    刪除users集合下所有資料
  • db.users.remove({"name": "lecaf"})    刪除users集合下name=lecaf的資料
  • db.users.drop()或db.runCommand({"drop","users"})    刪除集合users
  • db.runCommand({"dropDatabase": 1})    刪除當前資料庫

4. 查詢

  • db.users.find()    查詢users集合中所有資料
  • db.users.findOne()    查詢users集合中的第一條資料

5. 修改

  • db.users.update({"name":"lecaf"}, {"age":10})    修改name=lecaf的資料為age=10,第一個引數是查詢條件,第二個引數是修改內容,除了主鍵,其他內容會被第二個引數的內容替換,主鍵不能修改。

6. 例項

> show dbs            //顯示資料庫列表
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

> use test            //進入test資料庫,大小寫敏感,沒有這個資料庫也不要緊
switched to db test

> show collections    //顯示資料庫中的集合,相當於表格
runoob

> db.runoob.find()    //查詢
{ "_id" : ObjectId("5bdfa9de80d8af2cf6fbc2fb"), "x" : 10 }
{ "_id" : ObjectId("5bdfd97980d8af2cf6fbc2fc"), "name" : "rmk", "age" : 22 }
{ "_id" : ObjectId("5bdfda9c80d8af2cf6fbc2fe"), "b" : 15, "d" : 25 }

> db.runoob.insert({"str1":hello,"str2":world})        //新增錯誤
2018-11-05T14:03:41.024+0800 E QUERY    [js] ReferenceError: hello is not define
d :
@(shell):1:12
//hello沒有加引號,只有數字可以不加引號,或者是變數,現在是定義字串“hello”

> db.runoob.insert({"str1":"hello","str2":"world"})    //新增
WriteResult({ "nInserted" : 1 })

> db.runoob.find()    //查詢
{ "_id" : ObjectId("5bdfa9de80d8af2cf6fbc2fb"), "x" : 10 }
{ "_id" : ObjectId("5bdfd97980d8af2cf6fbc2fc"), "name" : "rmk", "age" : 22 }
{ "_id" : ObjectId("5bdfda9c80d8af2cf6fbc2fe"), "b" : 15, "d" : 25 }
{ "_id" : ObjectId("5bdfdd7980d8af2cf6fbc2ff"), "str1" : "hello", "str2" : "worl
d" }

> db.runoob.find({"name":"rmk"})    //按條件查詢
{ "_id" : ObjectId("5bdfd97980d8af2cf6fbc2fc"), "name" : "rmk", "age" : 22 }

> db.runoob.update({"str1":"hello"},{"str2":"China"})    //更新資料
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.runoob.find()    //查詢更新後的結果
{ "_id" : ObjectId("5bdfa9de80d8af2cf6fbc2fb"), "x" : 10 }
{ "_id" : ObjectId("5bdfd97980d8af2cf6fbc2fc"), "name" : "rmk", "age" : 22 }
{ "_id" : ObjectId("5bdfda9c80d8af2cf6fbc2fe"), "b" : 15, "d" : 25 }
{ "_id" : ObjectId("5bdfdd7980d8af2cf6fbc2ff"), "str2" : "China" }

> db.runoob.remove({"str2":"China"})    //按條件刪除
WriteResult({ "nRemoved" : 1 })

> db.runoob.find()    //查詢刪除後的結果
{ "_id" : ObjectId("5bdfa9de80d8af2cf6fbc2fb"), "x" : 10 }
{ "_id" : ObjectId("5bdfd97980d8af2cf6fbc2fc"), "name" : "rmk", "age" : 22 }
{ "_id" : ObjectId("5bdfda9c80d8af2cf6fbc2fe"), "b" : 15, "d" : 25 }

六、高階應用

1. 條件查詢

  • db.collection.find({ "key" : value })           查詢key=value的資料
  • db.collection.find({ "key" : { $gt: value } })      key > value
  • db.collection.find({ "key" : { $lt: value } })      key < value
  • db.collection.find({ "key" : { $gte: value } })     key >= value
  • db.collection.find({ "key" : { $lte: value } })      key <= value
  • db.collection.find({ "key" : { $gt: value1 , $lt: value2 } })    value1 < key <value2
  • db.collection.find({ "key" : { $ne: value } })    key <> value
  • db.collection.find({ "key" : { $mod : [ 10 , 1 ] } })    取模運算,條件相當於key % 10 == 1 即key除以10餘數為1的
  • db.collection.find({ "key" : { $nin: [ 1, 2, 3 ] } })    不屬於,條件相當於key的值不屬於[ 1, 2, 3 ]中任何一個
  • db.collection.find({ "key" : { $in: [ 1, 2, 3 ] } })    屬於,條件相當於key等於[ 1, 2, 3 ]中任何一個
  • db.collection.find({ "key" : { $size: 1 } })    $size 數量、尺寸,條件相當於key的值的數量是1(key必須是陣列,一個值的情況不能算是數量為1的陣列)
  • db.collection.find({ "key" : { $exists : true|false } })    $exists 欄位存在,true返回存在欄位key的資料,false返回不存在字度key的資料
  • db.collection.find({ "key": /^val.*val$/i })    正則,類似like;“i”忽略大小寫,“m”支援多行
  • db.collection.find({ $or : [{a : 1}, {b : 2} ] })    $or或 (注意:MongoDB 1.5.3後版本可用),符合條件a=1的或者符合條件b=2的資料都會查詢出來
  • db.collection.find({ "key": value , $or : [{ a : 1 } , { b : 2 }] })    符合條件key=value ,同時符合其他兩個條件中任意一個的資料
  • db.collection.find({ "key.subkey" :value })    內嵌物件中的值匹配,注意:"key.subkey"必須加引號
  • db.collection.find({ "key": { $not : /^val.*val$/i } })    這是一個與其他查詢條件組合使用的操作符,不會單獨使用。上述查詢條件得到的結果集加上$not之後就能獲得相反的集合。

2. 排序

  • db.collection.find().sort({ "key1" : -1 ,"key2" : 1 })    這裡的1代表升序,-1代表降序

3. 其他

  • db.collection.find().limit(5)    控制返回結果數量,如果引數是0,則當作沒有約束,limit()將不起作用
  • db.collection.find().skip(5)    控制返回結果跳過多少數量,如果引數是0,則當作沒有約束,skip()將不起作用,或者說跳過了0條
  • db.collection.find().skip(5).limit(5)    可用來做分頁,跳過5條資料再取5條資料
  • db.collection.find().count(true)    count()返回結果集的條數
  • db.collection.find().skip(5).limit(5).count(true)    在加入skip()和limit()這兩個操作時,要獲得實際返回的結果數,需要一個引數true,否則返回的是符合查詢條件的結果總數