MongoDB在python中的使用
-
mongoDB是由C++編寫的分佈式文檔數據庫。
-
內部使用類似於Json的bson格式。
安裝
- https://www.mongodb.com/download-center/communitywindows下載官方zip,解壓即可使用。
組件 | 文件名 |
---|---|
Server | mongod.exe |
Router | mongos.exe |
Client | mongo.exe |
MonitoringTools | mongostat.exe,mongotop.exe |
importExportTools | mongodump.exe,mongorestore.exe,mongoexport.exe,mongoimport.exe |
MiscellaneousTools | bsondump.exe,mongofiles.exe,mongooplog.exe,mongoperf.exe |
- 運行
$ pwd
/d/Application/mogodb/package/mongodb4.0/bin
gdy@gdy MINGW64 /d/Application/mogodb/package/mongodb4.0/bin
$ ./mongod.exe
2019-08-13T22:01:34.963+0800 I STORAGE [main] Max cache overflow file size custom option: 0
2019-08-13T22:01:35.408+0800 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2019-08-13T22:01:35.412+0800 I CONTROL [initandlisten] MongoDB starting : pid=20852 port=27017 dbpath=D:\data\db\ 64-bit host=gdy
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] db version v4.0.12
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] git version: 5776e3cbf9e7afe86e6b29e22520ffb6766e95d4
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] allocator: tcmalloc
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] modules: none
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] build environment:
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] distmod: 2008plus-ssl
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] distarch: x86_64
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] target_arch: x86_64
2019-08-13T22:01:35.413+0800 I CONTROL [initandlisten] options: {}
2019-08-13T22:01:35.434+0800 I STORAGE [initandlisten] exception in initAndListen: NonExistentPath: Data directory D:\data\db\ not found., terminating
2019-08-13T22:01:35.434+0800 I NETWORK [initandlisten] shutdown: going to close listening sockets...
2019-08-13T22:01:35.434+0800 I CONTROL [initandlisten] now exiting
2019-08-13T22:01:35.434+0800 I CONTROL [initandlisten] shutting down with code:100
gdy@gdy MINGW64 /d/Application/mogodb/package/mongodb4.0/bin
$
- 啓動服務出錯,原因在於找不到數據目錄。windows下創建該目錄
D:\data\db\
- 選項說明
--bind_ip ip
逗號分隔ip地址。默認localhost--bing_ip_all
綁定所有本地ip地址--port port
端口,默認27017--dbpath path
數據路徑,缺省爲\data\db\
。windows下缺省就是當前盤符的根目錄--logpath path
指定日誌文件,替代stdout,說明默認是控制檯打印日誌-f file
指定配置文件,yaml格式註冊wiendows服務
- –install 註冊windwos服務
- –serviceName name 服務名稱
- –serviceDisplayName name 服務顯示名
配置文件
-
mongodb配置使用YAML格式
-
嵌套使用縮進晚餐,不支持Tab等製表符,支持空格
-
冒號後要有空格
-
在mongodb安裝目錄新建配置文件mongodb.yml。內容如下:
systemLog:
destination: file
path: "D:/Application/mogodb/package/mongodb4.0/mongod.log"
logAppend: true
storage:
dbPath: "D:/Application/mogodb/package/mongodb4.0/db"
net:
bindIp: 127.0.0.1
port: 27017
- 在對應目錄建立
D:/Application/mogodb/package/mongodb4.0/db
文件夾
-
選項
- systemLog
- destination,缺省是輸出日誌到std,file表示輸出到文件
- path,日誌路徑
- logAppend,true表示在已存在的日誌文件追加。默認false,每次啓動服務,重新創建新的日誌。
- storage
- dbPath,必須指定,mongodb的數據目錄
- net
- bindlp,缺省綁定到127.0.0.1
- port,端口,缺省爲27017,客戶端連接用
- systemLog
-
windows下注冊爲服務的命令如下,使用了配置文件:
mongod.exe -f "D:/Application/mogodb/package/mongodb4.0/mongod.yml" --serviceName mongod --serviceDisplayName mongo --install
-
去掉配置文件中的配置日誌信息部分。這樣日誌將會顯示在控制檯
storage:
dbPath: "D:/Application/mogodb/package/mongodb4.0/db"
net:
bindIp: 127.0.0.1
port: 27017
- 控制檯執行命令爲:
$ pwd
/d/Application/mogodb/package/mongodb4.0/bin
gdy@gdy MINGW64 /d/Application/mogodb/package/mongodb4.0/bin
$ ./mongod.exe -f ../mongodb.yml
客戶端
- 客戶端連接
$ bin/mongo.exe
MongoDB shell version v4.0.12
help 打開幫助
show dbs 查看當前庫
use blog 有就切換過去,沒有就創建後切換過去。剛創建的並不在數據庫列表中,需要寫入數據後才能看到
db 查看當前數據庫
db.users.insert({user:"tom",age:20}) db指代當前數據庫;users集合名
Pychar插件
- 在settings/plugins中輸入mongo,安裝Mongo Plugin,完成後重啓Pycharm。
- 菜單項view/Tool windows/Mongo Explorer
Python鏈接
- Mongodb官方推薦使用pymongo。參考https://docs.mongodb.com/ecosystem/drivers/pymongo/
- 本次Mongodb使用的是3.6,需要pymongo 3.6以上。缺省安裝pymongo 3.8,目前兼容Python 3.4+。
- mongodb的鏈接字符串
mongodb://gdy:[email protected]:27017/test
from pymongo import MongoClient
# client = MongoClient(host="127.0.0.1",port=27017) #客戶端連接
client = MongoClient("mongodb://127.0.0.1:27017")
print(client)
# db = client.blog
db = client["blog"] #指定數據庫
print(db)
# users = db["users"]
users = db.users #集合
print(users)
Mongodb基本使用
基本概念
- MongoDB中可以創建使用多個庫,但有一些數據庫名是保留的,可以直接訪問這些特殊作用的數據庫。
- admin:從權限的角度來看,這是"root"數據庫。要是將一個用戶添加到這個數據庫,這個用戶自動繼承所有數據庫的權限。一些特定的服務器端命令也只能從這個數據庫運行,比如列出所有的數據庫或者關閉服務器。
- local:這個數據永遠不會被賦值,可以用來存儲限於本地單臺服務器的任意集合
- config:當Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。
MongoDB | RDBMS |
---|---|
Database | Database |
Table | Collection |
Row | Document |
Column | Field |
Join | Embedded Document嵌入文檔或Reference引用 |
Primary Key | 主鍵(MongoDB提供了Key爲_id) |
插入數據
- 每條數據插入後都有一個唯一key,屬性
_id
唯一標識一個文檔。沒有沒有顯示指明該屬性,會自動生成一個Objectld類型的_id
屬性。 - pymongo.collection.Collection類
- db.collection.insert_one(dict)->InsertOneResult #單行插入
- dict是一個字典
- InsertOneResult:f返回結果ObjectId對象,即
_id
的值
- db.collection.insert_many([dict,…])->[InsertOneResult,…] #多行插入
- 第一個參數是個列表,列表中記錄需要插入的文檔類型即dict
- 返回結果,被插入的對象所獲得的id
- db.collection.insert_one(dict)->InsertOneResult #單行插入
from pymongo import MongoClient
from pymongo.results import InsertOneResult
from pymongo.collection import Collection
# client = MongoClient(host="127.0.0.1",port=27017) #客戶端連接
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
user1 = {"id":1,"name":"ben","age":20}
# users.insert(user1) #已經過期
#單條插入
x:InsertOneResult = users.insert_one(user1)
print(type(x),x)
print(x.inserted_id)
user2 = {"id":257,"name":"tom","age":32}
user3 = {"id":258,"name":"jerry","age":18}
#批量插入
result = users.insert_many([user2,user3])
print(result.inserted_ids)
#[ObjectId('5d539433c1b3dcb23654814d'), ObjectId('5d539433c1b3dcb23654814e')]
#大小寫敏感
user4 = {"id":"3","name":"tom","age":20,"Name":"tommy"}
x = users.insert_one(user4)
print(x.inserted_id)
- 插入後的數
ObjectID
-
ObjectID由12個字節組成
- 4個字節時間戳
- 3個字節機器識別碼
- 2個字節進程id
- 3個字節隨機數
-
根據上面的objectID(5d539433c1b3dcb23654814d)驗證
import datetime
t = "5d539433c1b3dcb23654814d"[:8] #時間戳提取
print(t)
x = int.from_bytes(bytearray.fromhex(t),"big")
print(hex(x),x)
print(datetime.datetime.fromtimestamp(x))
# 也可以使用函數獲取
import bson
dat = bson.ObjectId("5d539433c1b3dcb23654814d").generation_time
print(dat,dat.timestamp())
文檔
- mongodb數據類型參考https://docs.mongodb.com/v3.6/reference/bson-types/
- 每一條記錄對應一個文檔,其格式使用BSON。BSON即Binary Json。
- BSON二進制格式如下:
- 可以查看"D:\Application\mogodb\package\mongodb4.0\db\collection-4-*.wt"對應的二進制格式
00 00 05 82 d7 35 00 00 00 07 5f 69 64 00 5d 45
35
表示文檔二精製數據長度07
表示MongoDB中特殊數據類型ObjectID5f 69 64
,ascii碼_id
57 be 12 f2 bf 14 48 c7 43 de 10 69 64 00 01 01
5d 45 57 be 12 f2 bf 14 48 c7 43 de
,ObjectId(‘5d4557be12f2bf1448c743de’)_id的值10 69 64
,10表示類型int-32,69 64
是ascii碼id0101
小端模式,十進制257
00 00 02 6e 61 6d 65 00 04 00 00 00 74 6f 6d 00
02
表示數據類型UTF-8 String6e 61 6d 65
表示字符串name04
,表示字符串長度74 6f 6d 00
,表示字符串tom和結束符
10 61 67 65 00 20 00
10
,表示數據類型int-3261 67 65
,表示字符串age20
,表示十進制32
- 文檔
- 文檔中,使用鍵值對
- 文檔中的鍵/值對時有序的
- 鍵是字符串
- 區分大小寫,使用UTF-8字符
- 鍵不能含有\0(空字符)。這個字符用來表示鍵字符串的結尾
.
和$
有特別的意義,只有在特定環境下才能使用- 以下劃線
_
開頭的鍵是保留的,例如:_id
- 值可以是:
- 字符串,32位或64位整數、雙精度、時間戳(毫秒)、布爾型、null
- 字節數組、BSON數組、BSON對象
查詢數據
- pymongo.collection.Collection類
- db.collection.find_one(dict)->result 查詢單條數據
- db.collection.find(dict)->resutl 查詢多條數據
- dict,使用查詢操作符組成的字典
- result,返回的結果集
- 單條查詢
from pymongo import MongoClient
from pymongo.collection import Collection
from bson.objectid import ObjectId
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
# 查詢
result = users.find_one({"name":"tom"})
print(type(result),result)
# 使用key查詢
result2 = users.find_one({"_id":ObjectId("5d539433c1b3dcb23654814d")})
print(type(result2),result2)
#查不到,返回None
result3 = users.find_one({"name":"tommy"})
print(type(result3),result3)
- 多條查詢
from pymongo import MongoClient
from pymongo.collection import Collection
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
# 多條查詢
results = users.find({"name":"tom"})
print(type(results))
print(results)
print("- "*30)
for x in results:
print(type(x),x)
- 查詢操作符
比較符號 | 含義 | 示例 |
---|---|---|
$lt |
小於 | {"age":{"$lt":20}} |
$gt |
大於 | {"age":{"$gt":20}} |
$lte |
小於等於 | {"age":{"$lte":20}} |
$gte |
大於等於 | {"age":{"$gte":20}} |
$ne |
不等於 | {"age":{"$ne":20}} |
$eq |
等於,可以不用增符號 | {"age":{"$eq":20}} |
$in |
在範圍內 | {"age":{"$in":[20,23]}} |
$nin |
不在範圍內 | {"age":{"$nin":[20,30]]}} |
邏輯符號 | 含義 | 示例 |
---|---|---|
$and |
與 | {"$and":[{"name":"tom"},{"age":{"$gt":20}}]} |
$or |
或 | |
$not |
非 |
元素 | 含義 | 示例 |
---|---|---|
$regex |
文檔中字段內容匹配 | {"name":{"$regex":"^t"}} |
$mod |
取模 | {"age":{"$mod":[10,2]}} 模10餘2 |
統計
- db.collection.find(條件字典).count() 統計次數(已過時)
- db.collection.count_documents(條件字典)
from pymongo import MongoClient
from pymongo.collection import Collection
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
# 統計
# 被棄用
# count = users.find({"age":{"$gt":10}}).count()
#求出age>10的數量
count = users.count_documents({"age":{"$gt":10}})
print(count) #返回結果4
排序
- db.collection.find().sort(字段名,排序規則)
- db.collection.find().sort(list)
- list爲一個列表,封裝多個排序規則的2元組,2元組第一個參數爲字段名,第二個參數爲排序規則
from pymongo import MongoClient
from pymongo.collection import Collection
import pymongo
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
# 排序
results = users.find().sort("age",pymongo.DESCENDING) #降序
print(*list(results),sep="\n")
print("- "*30)
results2 = users.find().sort(
[
("name",pymongo.DESCENDING),#name降序排列
("age",pymongo.ASCENDING) #age升序
]
)
print(*list(results2),sep="\n")
分頁
- db.collection.find().skip(n).limit(m) #分頁,查詢結果中跳過前n個,最多顯示m個
- skip(n):從查詢結果中跳過前面指定n個
- limit(m):從查詢結果中最多隻顯示m個
- skip跳過幾個,limit限制結果個數
from pymongo import MongoClient
from pymongo.collection import Collection
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
# 分頁
results = users.find()
print(*list(results),sep="\n")
print("- "*30)
results1 = users.find().skip(2) #跳過前2個
print(*list(results1),sep="\n")
print("- "*30)
results2 = users.find().skip(1).limit(2) #跳過前1個最多顯示2個
print(*list(results2),sep="\n")
print("- "*30)
更新
更新操作符 | 含義 | 示例 |
---|---|---|
$inc |
對給定字段數字值增減 | {"$inc":{"age":-5}} 對age的值-5 |
$set |
設置字段值,如果字段不存在則創建 | {"$set":{"gender":"M"}} |
$unset |
移除字段 | {"$unset":{"Name":""}} |
- db.collection.updateOne(查詢條件dict,更新dict)方法只更新查詢結果集中的第一個
- db.collection.update_many(查詢條件dict,更新dict)方法多行更新
- db.collection.replace_one(查詢條件,新文檔dict) 更新一個文檔,會將匹配到的第一個結果中的文檔替換爲新文檔。
- 替換文檔,更新除
_id
外的所有字段
- 替換文檔,更新除
- updateOne更新第一個示例
from pymongo import MongoClient
from pymongo.collection import Collection
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
print(*list(users.find()),sep="\n")
print("- "*30)
# 更新,將name爲tom的結果中第一行文檔中age增加5
result = users.update_one({"name":"tom"},{"$inc":{"age":5}})
print(type(result),result)
print(result.matched_count,result.modified_count)
print("- "*30)
print(*list(users.find()),sep="\n")
- update_many更新多行
from pymongo import MongoClient
from pymongo.collection import Collection
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
print(*list(users.find()),sep="\n")
print("- "*30)
# 更新,將name爲tom的字段都添加一個gender等於m的屬性
result = users.update_many({"name":"tom"},{"$set":{"gender":"M"}})
print(type(result),result)
print(result.matched_count,result.modified_count)
print("- "*30)
print(*list(users.find()),sep="\n")
print("- "*30)
# 更新,將有name爲tom的文檔中包含Name屬性的刪除
result = users.update_many({"name":"tom"},{"$unset":{"Name":""}})
print(type(result),result)
print(result.matched_count,result.modified_count)
print("- "*30)
print(*list(users.find()),sep="\n")
- replace_one替換一個文檔
- 更新除
_id
字段外的所有字段
- 更新除
from pymongo import MongoClient
from pymongo.collection import Collection
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
print(*list(users.find()),sep="\n")
print("- "*30)
# 替換文檔
result = users.replace_one({"name":"tom"},{"id":200,"name":"sam"})
print(type(result),result)
print("- "*30)
print(*list(users.find()),sep="\n")
刪除
- db.collection.remove(條件dict) #刪除,已過時的方法
- db.collection.delete_one(條件dict) #將滿足條件的結果刪除第一行
- db.collection.delete_many(條件dict)#將滿足條件的結果全部刪除
- db.collection.delete_many({})刪除所有文檔,慎用
from pymongo import MongoClient
from pymongo.collection import Collection
from pymongo.results import DeleteResult
client = MongoClient("mongodb://127.0.0.1:27017")
db = client["blog"] #指定數據庫
users:Collection = db.users #集合
print(*list(users.find()),sep="\n")
print("- "*30)
# 刪除age爲20的文檔,只刪除一條
result:DeleteResult = users.delete_one({"age":20})
print(type(result),result.deleted_count)
print("- "*30)
print(*list(users.find()),sep="\n")
# 刪除所有存在age字段的文檔
result2:DeleteResult = users.delete_many({"age":{"$exists":True}})
print(type(result2),result2.deleted_count)
print("- "*30)
print(*list(users.find()),sep="\n")