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,否則返回的是符合查詢條件的結果總數