MongoDB数据库的使用
推荐 菜鸟教程 + 大神笔记 + bili资源1 + bili资源2
1- MongoDB数据库的特点
由C++语言编写,基于分布式文件存储的开源数据库系统,旨在为WEB应用提供可扩展的高性能数据存储解决方案;
将数据存储为一个文档,数据结构由键值(key=>value)对组成,类似于JSON对象。字段值可以包含其他文档、数组和文档数组;如:
{
name: "sue",
age: 26,
status: "A",
groups: ['news', 'sports']
}
- GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
2- MySQL和MongoDB区别
SQL术语 | MongoDB数据库术语 | 解释 |
---|---|---|
database | database | 数据库 |
table | collection | 表格/集合 |
row | document | 数据行/文档 |
column | field | 数据列/域 |
index | index | 索引 |
primary key | primary key | 主键/MongoDB中主键是默认的,创建集合时自动创建主键(_id) |
表连接 | 无表连接 | MongoDB中无表连接 |
3- mongodb的一些简单终端操作
-
查看当前mongodb数据库的版本号
db.version() # 5.0.5
-
查看当前所在的数据库,默认是test数据库
db # test
-
查看当前数据库的链接地址
db.getMongo() # connection to 127.0.0.1:27017 (本地)
-
查看所有数据库
show databases / show dbs # 如果数据库中没有数据,则该数据库不会显示 # admin 0.000GB # config 0.000GB # local 0.000GB
-
切换数据库,如果数据库不存在,会先创建再切入(即数据库的隐式创建)
use class # switched to db class
-
创建集合
db.createCollection('集合名称')
-
查看集合
show tables / show collections
-
插入文档
db.集合名称.insert({键值对数据}) / db.集合名称.save({键值对数据}) > db.students.insert({'name': 'Mark', 'age': 20, 'height': 180}) WriteResult({ "nInserted" : 1 }) > db.studens.save({'name': "Jack", "age": 23, "height": 178}) WriteResult({ "nInserted" : 1 }) # 注意:如果想要插入多条数据,可以将多个对象放到一个数组中。 > db.students.insert([{'name': 'Hellen', 'age': 18, 'height': 168}, {'name': "John", "age": 22, "height": 180}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 2, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) # 注意:如果集合名不存在,会先创建再插入,即集合的隐式创建。
-
查询数据
db.集合名.find()
-
查询当前数据库的状态
db.stats() { "db" : "class", "collections" : 2, "views" : 0, "objects" : 4, "avgObjSize" : 66.5, "dataSize" : 266, "storageSize" : 57344, "freeStorageSize" : 16384, "indexes" : 2, "indexSize" : 57344, "indexFreeStorageSize" : 16384, "totalSize" : 114688, "totalFreeStorageSize" : 32768, "scaleFactor" : 1, "fsUsedSize" : 116896038912, "fsTotalSize" : 196495798272, "ok" : 1 }
-
删除集合
db.集合名.drop()
-
删除当前所在的数据库
db.dropDatabase()
修改/更新数据
db.集合名.update(query, update[, upsert, multi])
# query:必要参数,条件(小于:$lt,大于:$gt,等于:$eq,不等于:$ne,大于等于:$gte,小于等于:$lte)
# update:必要参数,更新的数据。 $set:设置值,$inc:增长值,$rename:重命名,$unset:删除
# upsert:可选参数,布尔值,表示如果不存在update数据,是否插入更新的数据。默认false,表示不插入,true表示插入
# multi:可选参数,布尔值,表示是否将查询结果中数据进行全部更新。默认false,表示更新第一条,true表示全部更新
-
删除文档
db.集合名.remove(query[, justOne]) db.集合名.remove({}) # 删除全部文档 # justOne:可选参数,布尔值,默认false,表示符合条件的全部删除,true表示只删除符合条件的一条数据。
-
查询文档
db.集合名.find() # 表示查询所有文档 db.集合名.find(query) # 表示查询所有符合条件的文档 db.集合名.find(query, projection) # 表示显示查询符合条件的某些键值 > db.students.find() { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b23"), "name" : "Hellen", "age" : 18, "height" : 168 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b24"), "name" : "John", "age" : 22, "height" : 180 } > db.students.find().pretty() # 格式化输出 { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b23"), "name" : "Hellen", "age" : 18, "height" : 168 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b24"), "name" : "John", "age" : 22, "height" : 180 } > db.students.find({'name': 'Mark'}, {'age': 1}) { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "age" : 20 } > db.students.find({'name': 'Mark'}, {'age': 0}) # 0不显示,1显示 { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "height" : 180 } db.集合名.findOne([query, preojection]) #只查询一条数据,返回的是格式化数据,不能和pretty()方法联合使用了,会报错
-
多条件查询
- and
sql: select * from 表 where xxx and xxx mongodb: db.集合名.find({k1: v1, k2: v2, ...}) > db.students.find({'name': 'Mark', 'age': 20}) { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 }
- or
sql: select * from 表 where xxx or xxx mongodb: db.集合名.find({'$or': [{k1: v1}, {k2: v2}, ...]}) > db.students.find({'$or': [{'age': {'$lte': 22}},{ 'height': 168}]}) { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b23"), "name" : "Hellen", "age" : 18, "height" : 168 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b24"), "name" : "John", "age" : 22, "height" : 180 }
-
查询某一列去重后的数据
sql: select distinct 字段 from 表 mongodb: db.集合名.distinct(key) > db.students.distinct('height') [ 168, 180 ]
-
限制查询
sql: select * from 表 limit 2 mongodb: db.集合名.find().limit(n) # n代表数字,代表查询前n条数据 > db.students.find().limit(2) { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b23"), "name" : "Hellen", "age" : 18, "height" : 168 }
-
跳过操作
sql: select * from 表 limit 2, 3 mongodb: db.集合名.find().skip(n) # n表示跳过前n条,从第n+1条开始查询
-
分页操作
sql: select * from 表 limit 2, 3 mongodb: db.集合名.find().skip(n).limit(m) # n表示跳过前n条,从第n+1条开始查询m条记录
-
排序
sql: select * from 表 order by 字段 asc/desc mongodb: db.集合名.find().sort({'k': 1(正序)/-1(倒序)}) > db.students.find().sort({'age': 1}) { "_id" : ObjectId("61bd8e0f86bc7040ca640b23"), "name" : "Hellen", "age" : 18, "height" : 168 } { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 } { "_id" : ObjectId("61bd8e0f86bc7040ca640b24"), "name" : "John", "age" : 22, "height" : 180 }
-
统计方法
sql: select count(*) from 表 mongodb: db.集合名.find().count() > db.students.find().count() 3
-
模糊查询
sql: select * from 表 where 字段 like %xxx% mongodb: db.集合名.find({'k': '/xxx/'}) > db.students.find({'name': /a/}) { "_id" : ObjectId("61bd8d3686bc7040ca640b21"), "name" : "Mark", "age" : 20, "height" : 180 }
4- PyMongo使用
-
创建数据库
import pymongo myclient = pymongo.MongoClient('mongodb://localhost:27017/') # myclient = pymongo.MongoClient(host='127.0.0.1', port=27017) mydb = myclient['test_ex']
-
判断数据库是否存在
dblist = myclient.list_datebase_names() if 'test_ex' in dblist: print("数据库已存在!") else: print("数据库不存在。")
-
创建集合
mycol = myclient['test_ex']['grade'] # 方括号的方式选择数据库和集合
-
判断集合是否存在
collist = mydb.list_collection_names() if 'grade' in collist: print("集合已存在!") else: print("集合不存在。")
5- 实操示例
import pymongo
myclient = pymongo.MongoClient('mongodb://localhost:27017/') # 实例化client,建立连接
test1218_db = myclient['test_1218']
test1218_db_students = myclient['test_1218']['students']
# 插入一条数据
ret = test1218_db_students.insert({'name': "test_Mark", "age": 20})
print(ret)
test1218_db_students.insert({'name': "test_Mark", "age": 18})
test1218_db_students.insert({'name': "test_Mark", "age": 33})
# 插入多条数据
data_list = [{"name": "test_Harry{}".format(i)} for i in range(10)]
ret_many = test1218_db_students.insert_many(data_list)
for i in ret_many.inserted_ids:
print(i)
# 删除一个文档
n1 = test1218_db_students.delete_one({'name': "test_Mark"})
# 删除所有满足条件的文档
n_over2 = test1218_db_students.delete_many({'name': "test_Mark"})
# 更新一个文档
p1 = test1218_db_students.update_one({'name': "test_Mark"}, {"$set": {"name": "new_test_Mark"}})
# 更新全部符合条件文档
p_over2 = test1218_db_students.update_many({'name': "test_Mark"}, {"$set": {"name": "new_test_Mark"}})
# 查找一个文档
k1 = test1218_db_students.find_one({"name": "test_Mark"})
# 查找num个满足条件的文档
k1_num = test1218_db_students.find({"name": "test_Mark"}).limit(num)
# 查找所有满足条件的文档,如条件为空,则返回数据库的所有
k_over2 = test1218_db_students.find({"name": "test_Harry6"})
# k_over2是一个Cursor游标对象,可迭代,类似读取文件的指针
for i in k_over2:
print(i)
for j in k_over2:
print(j) # 此时j中无内容
# 查找所有满足条件的文档,并排序, 1表示升序,-1表示降序
k_over2_sorted = test1218_db_students.find({"name": "test_Harry6"}).sort('age', -1)