本文介绍了如何使用
MongoDB
的 CURD, 及使用PyMongo
进行相应操做, 是一篇扫盲贴.sql
# 安装
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
复制代码
# 安装
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
复制代码
学技术仍是用Linux吧, 虚拟机装ubuntu.
mongodb 不支持 WSL.
复制代码
在使用mongodb前咱们先理一下概念, 与关系型数据库不一样, mongodb是非关系型文档数据库. 它没有外键的说法, 保存的是 BSON(相似JSON的数据结构).mongodb
从pymongo拿来的示意图很好的解释了它的数据结构.shell
与关系型数据库的概念对比数据库
关系型概念 | MongoDB 等价概念 |
---|---|
Database | Database |
Tables | Collections |
Rows | Documents |
Index | Index |
最大的区别是咱们再也不受表结构的限制, 能够写入各类json. 反正咱们操做的就是一条记录麻, 无论一条条row, 仍是一个个json document(这是一把双刃剑).json
咱们能够进入 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
复制代码
命令:数据结构
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" } }
])
复制代码
命令:
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
复制代码
命令:
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
复制代码
命令:
db.collection.deleteOne() # 删除一条
db.collection.deleteMany() # 删除一条
复制代码
举例
db.inventory.deleteOne({status:"A"}) # 匹配条件,删一条
db.inventory.deleteMany({status:"A"}) # 删除全部匹配条件的记录
db.inventory.deleteMany({}) # 全删全部inventory下的document
复制代码
聚合管道, 意思就是把多个聚合操做一步步执行.
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 }
复制代码
PyMongo
是官网库, 熟悉完 mongo 的原生命令, 使用pymongo就是类推.
pip install pymongo
复制代码
from pymongo import MongoClient
client = MongoClient()
db = client.test # 这里用回测试的db
# 测试一下, 把以前插入的数据所有输出
result = db.inventory.find({})
for d in result:
print(d)
复制代码
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)
复制代码
# 聚合查询并按公司名, 部门排序
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)
复制代码
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)
复制代码
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 几乎是一致的, 稍微转换一下能用.