MongoDB 及 PyMongo 的基本用法

本文介紹瞭如何使用 MongoDB 的 CURD, 及使用 PyMongo進行相應操做, 是一篇掃盲貼.sql

1. 安裝與運行

Mac
# 安裝
brew tap mongodb/brew
brew install mongodb-community@4.0

# 啓動
brew services start mongodb-community@4.0

# 日誌文件
/usr/local/var/log/mongodb/mongo.log

# 配置文件
/usr/local/etc/mongod.conf
複製代碼
Linux(ubuntu)
# 安裝
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org

# 啓動/中止/重啓
sudo service mongod start
sudo service mongod stop
sudo service mongod restart

# 日誌文件
/var/log/mongodb/mongod.log

# 配置文件
/etc/mongod.conf
複製代碼
Windows
學技術仍是用Linux吧, 虛擬機裝ubuntu.
mongodb 不支持 WSL.
複製代碼

2. 概念

在使用mongodb前咱們先理一下概念, 與關係型數據庫不一樣, mongodb是非關係型文檔數據庫. 它沒有外鍵的說法, 保存的是 BSON(相似JSON的數據結構).mongodb

從pymongo拿來的示意圖很好的解釋了它的數據結構.shell

與關係型數據庫的概念對比數據庫

關係型概念 MongoDB 等價概念
Database Database
Tables Collections
Rows Documents
Index Index

最大的區別是咱們再也不受表結構的限制, 能夠寫入各類json. 反正咱們操做的就是一條記錄麻, 無論一條條row, 仍是一個個json document(這是一把雙刃劍).json

3. Mongo Shell

咱們能夠進入 mongo shell 操做 mongodb. 也能夠另行下載帶界面的客戶端, 但自帶的工具已經夠用.canvas

進入 mongo shell, 列出db, collections.ubuntu

$ mongo
> show databases 
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

> use test # 使用指定db
switched to db test

> db # 顯示當前db
test

> show collections # 列出當前db下的collection
複製代碼

mongo的db和collection不須要顯式 create, 它們會在你插入時自動生成.bash

> use demo # 切換db, 切換db即建立
> db.inventory.insert({first_doc: "This is my first doc."})
WriteResult({ "nInserted" : 1 })

> show dbs # 這個demo db會在插入數據時自動建立
...
demo
...

> show collections # 這個collection會在插入數據時自動建立
inventory

> db.inventory.find({})
{ "_id" : ObjectId("5c9ad59a52fc8581a5707ce9"), "first_doc" : "This is my first doc." }

> db.inventory.drop() # 刪除collection
> db.dropDatabase() # 刪除db
複製代碼
insert

命令:數據結構

db.collection.insertOne() # 插入一條collection
db.collection.insertMany() # 插入多條
db.collection.insert() # 插入一或多條
複製代碼

舉例:app

db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

db.inventory.insert([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])
複製代碼
query

命令:

db.collection.findOne() # 查詢一條
db.collection.findMany() # 查詢多條
db.collection.find() # 查詢一或多條
複製代碼

舉例

db.inventory.find({}) # 至關於select * from inventory;

db.inventory.find({status: "D"})
# select * from inventory where status = 'D';

db.inventory.find({status: {$in: ["A", "D"]}})
# select * from inventory where status in ("A", "D");

db.inventory.find({status: "A", qty: {$lt: 30}})
# select * from inventory where status = 'A' and qty < 30;

db.inventory.find({$or: [{status: "A"}, {qty: {$lt: 30}}]})
# select * from inventory whre status = 'A' or qty < 30;

db.inventory.find({status: "A", $or: [{qty: {$lt: 30}}, {item: /^p/}]})
# select * from inventory where status = 'A' AND (qty < 30 OR item like 'p%');
複製代碼

操做符

: # =
$lt # <
$lte # <=
$gt # >
$gte # >=
$in # in
$or # or
{}, {} # ,是and
複製代碼
update

命令:

db.collection.updateOne() # 更新一條
db.collection.updateMany() # 更新多條
db.collection.replaceOne() # 替換一條
複製代碼

舉例

db.inventory.updateOne(
   { item: "journal" },
   {
     $set: { "size.uom": "in", status: "P" },
     $currentDate: { lastModified: true }
   }
)
# update inventory set size.uom='cm', status='P', 
# lastModified=NOW() where id in (
# select id from (
# select id from inventory where item ='paper' limit 1
# ) tmp
# );
# 爲了讓等價sql的正確性, 不得不寫很長.
# 實際這裏就是隻修改一條記錄的意思.

db.inventory.updateMany(
   { "qty": {$lt: 30}},
   {
     $set: { "size.uom": "cm", status: "A" },
     $currentDate: { lastModified: true }
   }
)
# 修改全部 qty < 30 的記錄.

db.inventory.replaceOne(
   { item: "mat" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)
# 匹配 item = mat 的一條記錄替換爲後面的 {item: ...}
複製代碼

操做符

$set # update set x = n
$inc # update set x = x + n
複製代碼
delete

命令:

db.collection.deleteOne() # 刪除一條
db.collection.deleteMany() # 刪除一條
複製代碼

舉例

db.inventory.deleteOne({status:"A"}) # 匹配條件,刪一條
db.inventory.deleteMany({status:"A"}) # 刪除全部匹配條件的記錄
db.inventory.deleteMany({}) # 全刪全部inventory下的document
複製代碼
aggregate pipeline

聚合管道, 意思就是把多個聚合操做一步步執行.

db.inventory.aggregate([
    {$match: {status: "A"}},
    {$group: {_id: "$item", total: {$sum: "$qty"}}}
])

# select sum('qty') as total, item as _id from inventory 
# where status = 'A' group by item;

{ "_id" : "notebook", "total" : 50 }
{ "_id" : "postcard", "total" : 45 }
{ "_id" : "journal", "total" : 25 }

複製代碼

4. PyMongo

PyMongo是官網庫, 熟悉完 mongo 的原生命令, 使用pymongo就是類推.

install
pip install pymongo
複製代碼
client
from pymongo import MongoClient

client = MongoClient()
db = client.test # 這裏用回測試的db

# 測試一下, 把以前插入的數據所有輸出
result = db.inventory.find({})
for d in result:
    print(d)

複製代碼
insert
names = ['JD','Ali','Ten', 'Bd', 'YZ']
company_area = ['Shengzhen', 'BeiJing', 'Shanghai', 'Hangzhou']
company_department = ['BD','Dev','Opt', 'UI', 'PM', 'QA']
company_worktime = ['996', '9116', '885', '997', '975']
docs = []
for x in range(1, 101):
    doc = {
        'name' : names[randint(0, (len(names)-1))],
        'area': company_area[randint(0, (len(company_area)-1))],
        'department': company_department[randint(0, (len(company_department)-1))],
        'total' : randint(1, 10),
        'worktime' : company_worktime[randint(0, (len(company_worktime)-1))] 
    }
    docs.append(doc)
db.reviews.insert_many(docs)
複製代碼

query
# 聚合查詢並按公司名, 部門排序

ret = db.reviews.aggregate([
    {'$group': {'_id': {'name':'$name', 'department': '$department'}, 'count': {'$sum': '$total'}}}, 
    {'$sort': {'_id.name': -1, '_id.department': -1}}
])

for r in ret:
    print(r)
複製代碼

update
db.reviews.update_many({'name': 'Ali', 'area':'Hangzhou', 'department':'QA'}, 
{'$inc': {'total': 1}
})

result = db.reviews.find({'name': 'Ali', 'area':'Hangzhou', 'department':'QA'})
for r in result:
    print(r)
複製代碼
delete
db.reviews.delete_many({'name': 'Ali', 'area':'Hangzhou', 'department':'QA'})

result = db.reviews.find({'name': 'Ali', 'area':'Hangzhou', 'department':'QA'})
for r in result:
    print(r)

複製代碼

pymongo 的用法跟 mondo shell 幾乎是一致的, 稍微轉換一下能用.

相關文章
相關標籤/搜索