NoSQL-MongoDB with python

前言:html

MongoDB,文檔存儲型數據庫(document store)。NoSQL數據庫中,它獨佔鰲頭,碾壓其餘的NoSQL數據庫。python

使用C++開發的,性能僅次C。與redis同樣,開源、高擴展、高可用。linux

基於分佈式文件存儲。分佈式:文件分開存的(由Google提出的mapreduce,是目前分佈式的鼻祖)。就像蘋果的iCloud,照片、文件分開存儲的。redis

紐約時報用的數據庫就是它(from wiki),360部分業務的數據庫也是它。並且聽說偉大的wiki,也是從曾經的MySQL遷移到了MongoDB。mongodb

MongoDB的適用場景能夠看下這篇文章:https://yq.aliyun.com/articles/64352數據庫

但要注意,MongoDB在使用過程當中會消耗大量磁盤空間和內存。並且,MongoDB它非事務機制,沒法保證事件的原子性。json

MongoDB不適合的場景:ubuntu

(1).需高度事務性的系統。當原子性操做失敗時,傳統的關係型數據庫支持回滾操做,以保證數據在操做過程當中的正確性。而目前,MongoDB暫不支持此事務。例如銀行或會計系統。windows

(2).傳統的商業智能應用。針對特定問題的BI數據庫須要高度優化的查詢方式。分佈式

(3).使用SQL方便時(關聯查詢)。MongoDB的查詢方式是JSON類型的查詢方式,雖然查詢也比較靈活,但若是使用SQL進行統計會比較方便時,這種狀況就不適合使用MongoDB。

 

MongoDB描述、層次結構:

(一).描述

MongoDB是文檔數據庫,以文檔爲單位。Bson文檔(Json的二進制)

與JS相關,內部引擎用了JS解釋器。

把一個文檔存儲爲Bson結構,在查詢時,轉換位Json對象,並能夠經過JS語法來操做。

(二).層次結構

庫 -> 集合 -> 文檔

 

MongoDB PK 傳統型數據庫:

傳統型數據庫:結構化數據,定好表結構後,每一行內容必須符合表結構,以致於每一行看起來都長得差很少。

MongoDB:以文檔爲單位,沒有表結構。表中的每篇文檔均可以有本身獨特的屬性和結構。

MongoDB最大的特色就是反範式化,管你幾張表,均可以一個文檔解決。每一個文檔至關於一棵樹,能夠無限伸枝。文檔與文檔之間相互獨立,沒有固定的結構。

(一).文檔的表現形式:一個Json對象,一個文檔

# 一個文檔
{
    id: 3
    name: "lisi"
    age: 10
}

# 另外一個文檔
{
    id: 4
    name: "wangwu"
    age: 20
    area: "nb"
    hobby: ["swimming", "football"]
}
View Code

(二).思考這麼一個問題:

以此https://movie.douban.com/subject/26861685/?from=showing爲例,設計一個影評數據庫。

傳統數據庫:影片信息一張表,影評一張表,回覆評論一張表,打分一張表。查詢起來至關費勁,關聯至關複雜。

MongoDB:上述內容所有丟進一個文檔中解決:

{
    file_name: "紅海行動"
    long_time: 120
    comment: [
        {
            comment1: "影評1"
            reply1: "好評"
        }
    ]
}
View Code

 

1、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)這項不填,就會得到全部數據庫。

 

2、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 update

sudo apt-get install -y mongodb-org

systemctl unmask mongodb

service mongodb start
View Code

這些操做後,MongoDB依然不會是最新版本,想要最新版去官網下載並進行源碼安裝。

(三).官方安裝

官方網站的安裝教程:https://docs.mongodb.com/manual/administration/install-community/

(1).安裝時遇到問題記錄,mark1

個人安裝方式是參考了官方教程上的更新apt索引方式進行安裝,安裝時因爲沒有靈活上網,致使下載速度極慢,因而強行終止了安裝進程,想要等會兒再試。結果當再次敲apt安裝命令時,就報了一大堆的錯誤。

後來Google一大通以後,終於解決了問題可以用上了,因而記錄下來了。

依次執行下面的linux代碼(我當時使用的是Ubuntu server 18.04 LTS 64bit):

sudo apt-get purge mongodb-org
sudo apt-get purge mongodb mongodb-server mongodb-server-core mongodb-clients
sudo apt-get autoremove
sudo apt-get update
sudo apt-get install mongodb-org
sudo dpkg --remove --force-remove-reinstreq mongo-tools
sudo dpkg --remove --force-remove-reinstreq mongodb-server-core
sudo apt-get --fix-broken install
sudo systemctl enable mongod
sudo service mongod restart

若是上面的命令仍是不能讓mongo服務跑起來,試一下下面的代碼(其實就是在上面的代碼中加了幾行文件夾設置命令):

sudo apt-get purge mongodb-org
sudo apt-get purge mongodb mongodb-server mongodb-server-core mongodb-clients
sudo apt-get autoremove
sudo apt-get update
sudo apt-get install mongodb-org
sudo dpkg --remove --force-remove-reinstreq mongo-tools
sudo dpkg --remove --force-remove-reinstreq mongodb-server-core
sudo apt-get --fix-broken install

mv /var/lib/mongodb /var/lib/mongodb_backup
mkdir /var/lib/mongodb
chmod 700 /var/lib/mongodb
chown mongodb:daemon /var/lib/mongodb

sudo systemctl enable mongod
sudo service mongod restart

 

3、MongoDB原生態命令

(一).插入文檔

命令格式:db.collection_name.insert()小括號裏寫json

例如:

db.biancheng.insert({name:"yekai",age:35,sex:"man",info:{like:"drink",wuqi:"feidao"}})
View Code

(二).更新文檔

(1).只更新指定的數據

db.collection_name.update({查詢條件json},{$set:{新數據json1,新數據json2,...}})

例如:

db.biancheng.update({name:"yekai"},{$set:{name:"yekai1",age:40}})
View Code

 

4、python3操做MongoDB

(一).鏈接localhost server,建立一個新數據庫

注意:MongoDB的默認端口號是27017,跟其餘數據庫同樣,建立鏈接時要寫上。

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)

# 也能夠寫成
# conn = MongoClient("mongodb://localhost:27017")

db = conn.testdb  # 建立數據庫

conn.close()
View Code

MongoDB不須要提早建立好數據庫,能夠直接"鏈接對象.數據庫名稱"。若是沒有這個數據庫,則會自動建立。若是有這個數據庫了,就會鏈接上。

可是,若是該數據庫中沒有數據,則不會顯示在管理工具裏面。

(二).增。

(1).插入單個文檔

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

# db = MongoClient("localhost", 27017).testdb
# 這樣寫的話,後面數據庫鏈接就無法關閉了。因此別偷懶,仍是要分開寫。

db.col.insert({"name": "quanquan616", "province": "浙江", "age": 30})  # col是表名

conn.close()
View Code

(2).插入多個文檔

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

db.col.insert([
    {"name": '張三', 'province': '浙江', 'age': 24},
    {"name": 'yuanyuan', 'province': '山東', 'age': 24},
    {"name": 'jt', 'province': '陝西', 'age': 30}
])

conn.close()
View Code

總結:插入多個文檔,insert()的括號中,須要用[]把元素包裹起來。insert([{},{},{}])

(三).刪。特別注意:remove()括號中不加條件,就會把表中的記錄全刪了!切記注意!否則得賠80個億,跳海喂鯊魚去吧……

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

db.col.remove({"name": "張三"})

conn.close()
View Code

(四).改。update({條件},{更新的數據})

把條件和更新的數據放進去update()的括號裏就能夠了。更新語句,注意格式別寫錯了,應該是{"$set":{"key":value}}

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

db.col.update({"name": "quanquan616"}, {"$set": {"age": 29}})

conn.close()
View Code

(五).查。

(1).使用find_one()查詢並返回第一個匹配到的文檔

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

db.col.find_one()

conn.close()
View Code

能夠把"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 MongoClient

conn = 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}
"""
View Code

(3).條件查詢

只須要將條件看成參數放進find()的括號中便可:

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

for item in db.col.find({"name": "quanquan616"}):
    print(item)

conn.close()
View Code

例1:查詢全部小於某個值的記錄

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

for 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}
"""
View Code

補充:大於的話,就把{"age":{"$lt":25}}中的lt換成gt

(4).統計記錄

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

db.col.find({"age": {"$eq": 30}}).count()  # 返回int,但不會直接顯示結果,須要賦值變量或者打印
# print(db.col.find({"age": {"$eq": 30}}).count())  # 2

conn.close()
View Code

(5).根據_id查詢記錄

須要引入一個庫,這個庫python3自帶了。from bson.objectid import ObjectId

from pymongo import MongoClient
from bson.objectid import ObjectId

conn = 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()
View Code

(6).排序。MongoDB默認升序排序。

sort()小括號中放入指定的key就能夠了:

from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

for 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}
"""
View Code

另外,能夠加入參數去設定排序方式。

好比倒序,例1:(須要引入pymongo)

import pymongo
from pymongo import MongoClient

conn = MongoClient("localhost", 27017)
db = conn.testdb

for item in db.col.find().sort("age", pymongo.DESCENDING):  # descending降序
    print(item)

conn.close()
View Code

(六).補充內容

(1).刪除一張表:db.drop_collection("table_name") 表和其中的數據同時刪除

(2).查看一個數據庫中全部的表:db.collection_names()

相關文章
相關標籤/搜索