前言:
MongoDB,文檔存儲型數據庫(document store)。NoSQL數據庫中,它獨占鰲頭,碾壓其他的NoSQL數據庫。
使用C++開發的,性能僅次C。與redis一樣,開源、高擴展、高可用。
基于分布式文件存儲。分布式:文件分開存的(由Google提出的mapreduce,是目前分布式的鼻祖)。就像蘋果的iCloud,照片、文件分開存儲的。
紐約時報用的數據庫就是它(from wiki),360部分業務的數據庫也是它。而且據說偉大的wiki,也是從曾經的MySQL遷移到了MongoDB。
MongoDB的適用場景可以看下這篇文章:https://yq.aliyun.com/articles/64352
但要注意,MongoDB在使用過程中會消耗大量磁盤空間和內存。而且,MongoDB它非事務機制,無法保證事件的原子性。
MongoDB不適合的場景:
(1).需高度事務性的系統。當原子性操作失敗時,傳統的關系型數據庫支持回滾操作,以保證數據在操作過程中的正確性。而目前,MongoDB暫不支持此事務。例如銀行或會計系統。
(2).傳統的商業智能應用。針對特定問題的BI數據庫需要高度優化的查詢方式。
(3).使用SQL方便時(關聯查詢)。MongoDB的查詢方式是JSON類型的查詢方式,雖然查詢也比較靈活,但如果使用SQL進行統計會比較方便時,這種情況就不適合使用MongoDB。
?
MongoDB描述、層次結構:
(一).描述
MongoDB是文檔數據庫,以文檔為單位。Bson文檔(Json的二進制)
與JS相關,內部引擎用了JS解釋器。
把一個文檔存儲為Bson結構,在查詢時,轉換位Json對象,并可以通過JS語法來操作。
(二).層次結構
庫 -> 集合 -> 文檔
?
MongoDB PK?傳統型數據庫:
傳統型數據庫:結構化數據,定好表結構后,每一行內容必須符合表結構,以至于每一行看起來都長得差不多。
MongoDB:以文檔為單位,沒有表結構。表中的每篇文檔都可以有自己獨特的屬性和結構。
MongoDB最大的特點就是反范式化,管你幾張表,都可以一個文檔解決。每個文檔相當于一棵樹,可以無限伸枝。文檔與文檔之間相互獨立,沒有固定的結構。
(一).文檔的表現形式:一個Json對象,一個文檔


# 一個文檔 {id: 3name: "lisi"age: 10 }# 另一個文檔 {id: 4name: "wangwu"age: 20area: "nb"hobby: ["swimming", "football"] }
(二).思考這么一個問題:
以此https://movie.douban.com/subject/26861685/?from=showing為例,設計一個影評數據庫。
傳統數據庫:影片信息一張表,影評一張表,回復評論一張表,打分一張表。查詢起來相當費勁,關聯相當復雜。
MongoDB:上述內容全部丟進一個文檔中解決:


{file_name: "紅海行動"long_time: 120comment: [{comment1: "影評1"reply1: "好評"}] }
?
一、install MongoDB for win7 32bit(萬事從安裝開始)
悲催的win7 32位系統,安裝MongoDB可是受盡折磨,不是執行命令后沒反應、就是因為32/64位的問題……
好在運氣不錯,找到了這篇文章:https://www.cnblogs.com/chenyucong/p/6217017.html 此博主提供了一個版本,本人跟著操作也行了。
直接照著那篇搞就可以:(配置命令去復制就可以了,自己敲會出錯,而且配置一次就完事了,又不是非要掌握的)
第一步操作成功:MongoDB的默認端口為27017
第二步配置:(注意環境變量的路徑大小寫,第一次沒成功,后來直接在地址欄上復制了路徑,成了!所以猜測,可能是因為路徑大小寫問題造成)
有時候電腦會抽風,即使配置好了環境變量,在C盤盤符下打這串命令會提示不是內部命令。那么直接cd進入mongodb/bin目錄,再執行這條命令,就行了。
可在系統服務中看到它了:
相對現在的新版本,這個算是很老的版本了,不過學習用應該是夠了。
MongoDB使用內存映射文件,32位系統上,數據庫容量最大上限為2G,關于這個內存映射文件,不了解也沒關系,影響不大。找來了偉大的wiki:https://zh.wikipedia.org/wiki/%E5%86%85%E5%AD%98%E6%98%A0%E5%B0%84%E6%96%87%E4%BB%B6
第三步:搞一個可視化管理工具
本來想用Robomongo(因為它界面很好看),但沒找到適用于win7 32位系統的[/噴血]。如有大大找到的話,懇請提供。
現在在用MongoVUE,專門用于windows系統的。填寫連接卡的時候,最后下面三個不填也可以連上。Name隨便寫,可以寫你喜歡的人的名字;Server:具體情況具體填,可以填一個遠程主機的IP;Database(s)這項不填,就會獲得所有數據庫。
?
二、install MongoDB on Ubuntu server
(一).簡易安裝
ubuntu server的apt秒天秒地,更新好apt之后直接鍵入命令:apt install mongodb
安裝完后,想要查看版本可用命令:mongo -version
用apt命令直接安裝不會是最新版本,最好去官網https://www.mongodb.com/download-center/community下載進行源碼安裝。
(二).源碼安裝
(三).在ubuntu server中的更新MongoDB


sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list sudo apt-get updatesudo apt-get install -y mongodb-orgsystemctl unmask mongodbservice mongodb start
這些操作后,MongoDB依然不會是最新版本,想要最新版去官網下載并進行源碼安裝。
?
三、MongoDB原生態命令
(一).插入文檔
命令格式:db.collection_name.insert()小括號里寫json
例如:


db.biancheng.insert({name:"yekai",age:35,sex:"man",info:{like:"drink",wuqi:"feidao"}})
(二).更新文檔
(1).只更新指定的數據
db.collection_name.update({查詢條件json},{$set:{新數據json1,新數據json2,...}})
例如:


db.biancheng.update({name:"yekai"},{$set:{name:"yekai1",age:40}})
?
四、python3操作MongoDB
(一).連接localhost server,創建一個新數據庫
注意:MongoDB的默認端口號是27017,跟其他數據庫一樣,創建連接時要寫上。


from pymongo import MongoClientconn = MongoClient("localhost", 27017)# 也可以寫成 # conn = MongoClient("mongodb://localhost:27017") db = conn.testdb # 創建數據庫 conn.close()
MongoDB不需要提前創建好數據庫,可以直接"連接對象.數據庫名稱"。如果沒有這個數據庫,則會自動創建。如果有這個數據庫了,就會連接上。
但是,如果該數據庫中沒有數據,則不會顯示在管理工具里面。
(二).增。
(1).插入單個文檔


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdb# db = MongoClient("localhost", 27017).testdb # 這樣寫的話,后面數據庫連接就沒法關閉了。所以別偷懶,還是要分開寫。 db.col.insert({"name": "quanquan616", "province": "浙江", "age": 30}) # col是表名 conn.close()
(2).插入多個文檔


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbdb.col.insert([{"name": '張三', 'province': '浙江', 'age': 24},{"name": 'yuanyuan', 'province': '山東', 'age': 24},{"name": 'jt', 'province': '陜西', 'age': 30} ])conn.close()
總結:插入多個文檔,insert()的括號中,需要用[]把元素包裹起來。insert([{},{},{}])
(三).刪。特別注意:remove()括號中不加條件,就會把表中的記錄全刪了!切記注意!不然得賠80個億,跳海喂鯊魚去吧……


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbdb.col.remove({"name": "張三"})conn.close()
(四).改。update({條件},{更新的數據})
把條件和更新的數據放進去update()的括號里就可以了。更新語句,注意格式別寫錯了,應該是{"$set":{"key":value}}


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbdb.col.update({"name": "quanquan616"}, {"$set": {"age": 29}})conn.close()
(五).查。
(1).使用find_one()查詢并返回第一個匹配到的文檔


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbdb.col.find_one()conn.close()
可以把"db.col.find_one()"放在print()中,這樣就可以看到打印出來的查詢結果了。print()之后的結果:{'_id': ObjectId('5a924d0f36af002d307cc30b'), 'name': 'quanquan616', 'province': '浙江', 'age': 30}
這個'_id':ObjectId('xxxxxxxxx')是自動生成的唯一值。
db.col.find_one({"name":"abc"}) 沒有找到文檔則返回None
(2).查詢所有記錄。可以使用find()函數,執行后返回的是一個結果集對象,需要用for循環遍歷出來。


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdb# print(db.col.find()) # <pymongo.cursor.Cursor object at 0x01D96210>for item in db.col.find():print(item)conn.close()""" # 遠行結果: {'_id': ObjectId('5a924d0f36af002d307cc30b'), 'name': 'quanquan616', 'province': '浙江', 'age': 30} {'_id': ObjectId('5a92520f36af001ca0fb665c'), 'name': '張三', 'province': '浙江', 'age': 24} {'_id': ObjectId('5a92520f36af001ca0fb665d'), 'name': 'yuanyuan', 'province': '山東', 'age': 24} {'_id': ObjectId('5a92520f36af001ca0fb665e'), 'name': 'jt', 'province': '陜西', 'age': 30} """
(3).條件查詢
只需要將條件當作參數放進find()的括號中即可:


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbfor item in db.col.find({"name": "quanquan616"}):print(item)conn.close()
例1:查詢所有小于某個值的記錄


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbfor item in db.col.find({"age": {"$lt": 25}}):print(item)conn.close()""" 運行結果: {'_id': ObjectId('5a92520f36af001ca0fb665c'), 'name': '張三', 'province': '浙江', 'age': 24} {'_id': ObjectId('5a92520f36af001ca0fb665d'), 'name': 'yuanyuan', 'province': '山東', 'age': 24} """
補充:大于的話,就把{"age":{"$lt":25}}中的lt換成gt
(4).統計記錄


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbdb.col.find({"age": {"$eq": 30}}).count() # 返回int,但不會直接顯示結果,需要賦值變量或者打印 # print(db.col.find({"age": {"$eq": 30}}).count()) # 2 conn.close()
(5).根據_id查詢記錄
需要引入一個庫,這個庫python3自帶了。from bson.objectid import ObjectId


from pymongo import MongoClient from bson.objectid import ObjectIdconn = MongoClient("localhost", 27017) db = conn.testdb# ObjectId是唯一的,所以用find_one()就可以了 db.col.find_one({'_id': {ObjectId('5a924d0f36af002d307cc30b')}}) # print(db.col.find_one({'_id': ObjectId('5a924d0f36af002d307cc30b')})) # {'_id': ObjectId('5a924d0f36af002d307cc30b'), 'name': 'quanquan616', 'province': '浙江', 'age': 30} conn.close()
(6).排序。MongoDB默認升序排序。
sort()小括號中放入指定的key就可以了:


from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbfor item in db.col.find().sort("age"):print(item)conn.close()""" 運行結果: {'_id': ObjectId('5a92520f36af001ca0fb665c'), 'name': '張三', 'province': '浙江', 'age': 24} {'_id': ObjectId('5a92520f36af001ca0fb665d'), 'name': 'yuanyuan', 'province': '山東', 'age': 24} {'_id': ObjectId('5a924d0f36af002d307cc30b'), 'name': 'quanquan616', 'province': '浙江', 'age': 30} {'_id': ObjectId('5a92520f36af001ca0fb665e'), 'name': 'jt', 'province': '陜西', 'age': 30} """
另外,可以加入參數去設定排序方式。
比如倒序,例1:(需要引入pymongo)


import pymongo from pymongo import MongoClientconn = MongoClient("localhost", 27017) db = conn.testdbfor item in db.col.find().sort("age", pymongo.DESCENDING): # descending降序print(item)conn.close()
(六).補充內容
(1).刪除一張表:db.drop_collection("table_name") 表和其中的數據同時刪除
(2).查看一個數據庫中所有的表:db.collection_names()
?