Mongodb简单操作
官方文档:https://docs.mongodb.com/v3.6/ 基本介绍: MongoDB 是由C++语言编写并基于分布式文件存储的开源数据库系统,是一款介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的NOSQL数据库。它面向文档存储,而且安装和操作起来都比较简单和容易,而且它支持各种流行编程语言进行操作,如PYTHON,JAVA,C++,PHP,C#,RUBY等。 MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 的文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
安装
# 如果要在ubuntu16.04中安装最新4.4版本mongodb,则需要完成以下命令步骤: # 导入包管理系统使用的公钥 wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - # 注册mongodb源 // 16.04 echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb- org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list # 更新源 sudo apt-get update # 安装mongodb sudo apt-get install -y mongodb-org=4.4.2 mongodb-org-server=4.4.2 mongodb-org- shell=4.4.2 mongodb-org-mongos=4.4.2 mongodb-org-tools=4.4.2 # 创建数据存储目录 sudo mkdir -p /data/db # 修改配置 /etc/mongodb.conf
启动
# 重新加载配置,并启动mongodb sudo systemctl daemon-reload sudo systemctl start mongod # 查看运行状态 sudo systemctl status mongod # 如果mongodb状态为stop,则运行 sudo systemctl enable mongod # 停止mongodb sudo systemctl stop mongod # 重启mongodb sudo systemctl restart mongod # 进入交互终端 mongo # 退出交互终端 exit
效果
MongoDB shell version v4.4.2 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("2c920d56-ddbb-4649-9191-a3bd4506a2d2") } MongoDB server version: 4.4.2 --- The server generated these startup warnings when booting: # 警告:强烈建议使用XFS文件系统,并使用WiredIger存储引擎。 # 解释:因为当前ubuntu使用的是ext4文件系统,mongodb官方建议使用XFS文件系统功能更能发挥mongodb的性能,忽略不管 2020-11-23T16:23:34.416+08:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem # 警告:当前mongodb没有为数据库启用访问控制。对数据和配置的读写访问是不受限制的。 # 解释:后面会创建数据库用户采用密码登陆的。暂时不用管 2020-11-23T16:23:35.046+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() ---
用户管理
# 内置角色 数据库用户角色:read、readWrite; 数据库管理角色:dbAdmin、dbOwner、userAdmin; 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager; 备份恢复角色:backup、restore; 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase 超级用户角色:root # 有几个角色间接或直接提供了系统超级用户的访问权限(dbOwner 、userAdmin、userAdminAnyDatabase) # 内置权限 Read:允许用户读取指定数据库 readWrite:允许用户读写指定数据库 dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户 clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。 readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限 readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限 userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。 root:只在admin数据库中可用。超级账号,超级权限 # Admin数据库(管理账号) # 创建账户管理员 use admin # 创建账户管理员 db.createUser({ user: "admin", pwd: "1", roles: [ {role: "userAdminAnyDatabase",db:"admin"} ] }) # 创建超级管理员 use admin # 创建超级管理员账号 db.createUser({ user: "root", pwd: "1", roles: [ { role: "root", db: "admin" } ] }) # 创建管理员用户 use mofang db.createUser({ user: "bajie", pwd: "1", roles: [ { role: "dbOwner", db: "mofang"} ] }) # 操作 show users # 查看当前库下的用户 db.system.users.find() # 查看系统中所有的用户 db.system.users.remove({user:"mofang"}) # 删除用户 db.changeUserPassword("mofang", "123456") # 修改密码 db.auth("root","123") # 登录 sudo mongod -f /etc/mongod.conf --fork --auth # 开启mongodb账户认证机制
基本操作
help # 查看帮助文档 db.serverStatus() # 当前服务器操作 db.getMongo() # 连接mongo的IP和端口 show logs # 查看现有的日志库 show log <logname> # 查看具体的日志库数据
术语对比
SQL | Mongodb |
---|---|
库(database) | 库(database) |
表(Talbe) | 集合(Collection) |
行/记录(Row) | 文档(Document) |
列/字段(Col) | 字段/域(Field) |
主键(Primary Key) | 对象ID(ObjectId) |
索引(Index) | 索引(Index) |
数据类型
Type | 描述 |
---|---|
ObjectID | 用于存储文档的ID,相当于主键 |
String | 字符串是最常用的数据类型,MongoDB中的字符串必须是UTF-8编码。 |
Integer | 整数类型用于存储数值。整数可以是32位,也可以是64位,这取决于你的服务器。 |
Double | 双精度类型用于存储浮点值,mongodb中没有float浮点数这个说法 |
Boolean | 布尔类型用于存储布尔值(true/ false) |
Arrays | 将数组、列表或多个值存储到一个键 |
Timestamp | 时间戳,用于记录文档何时被修改或创建。 |
Object | 用于嵌入文档,相当于子属性是另一个json而已 |
Null | 空值,相当于 python的None |
Symbol | 与字符串用法相同,常用于某些使用特殊符号的语言 |
Date | 用于以UNIX时间格式存储当前日期或时间。 |
Binary data | 二进制数据 |
Code | 用于将JavaScript代码存储到文档中 |
Regular expression | 正则表达式 |
库操作
show dbs # 显示所有数据库 use <database> # 切换数据库,不存在则创建 db.getName() # 查看当前使用的数据库 db.dropDatabase() # 删除当前数据库,不存在不报错 db.stats() # 查看当前数据库状态
集合操作
# 在mongodb中其实不创建集合,直接添加文档,mongodb也会自动生成集合的 db.test.insert({"_id":1,"name":"bajie"}) # 创建并添加文档 db.createCollection(name=<集合名称>, options = { capped : <boolean>, # 创建固定集合,固定集合指限制固定数据大小的集合,当数据达到最大值会自动覆盖最早的文档内容 size : <bytes_size>, # 指定固定集合存储的最大字节数,单位:字节数. max : <collection_size> # 指定固定集合中包含文档的最大数量,单位:字节数 } # 配置集合 show collections/tables # 查看当前库所有集合 db.<集合名称>.drop() # 删除集合 db.printCollectionStats() # 查看当前集合的创建信息
文档操作
增
db.集合名称.insert({"_id":1,"name":"bajie"}) # 添加一个文档 db.集合.insertOne(<document>) # 如果文档存在_id主键为更新数据,否则就添加数据。 db.集合.insertMany( [{"_id":1,"name":"bajie"},{"_id":2,"name":"bajie"}] ) # 一次性添加多个文档, 多次给同一个集合建议使用insertMany比insertOne效率更好
删
db.集合.remove( <query>, # remove的查询条件,一般写法:{"属性":{条件:值}},如果不填写条件,删除所有文档 { justOne: <boolean>, # 可选删除,是否只删除查询到的第一个文档,默认为false,删除所有 writeConcern: <document> # 可选参数,抛出异常的级别。 } ) db.mofang.remove({"_id":1,"name":"bajie"})
改
# 更新一条 db.集合.update( <query>, # update的查询条件,一般写法:{"属性":{条件:值}} <update>, # update的更新数据,一般写法 { $set:{"属性":"值"} } 或者 { $inc:{"属性":"值"} } { upsert: <boolean>, # 可选参数,如果文档不存在,是否插入objNew, true为插入,默认是false,不插入 multi: <boolean>, # 可选参数,是否把满足条件的所有数据全部更新 writeConcern: <document> # 可选参数,抛出异常的级别。 } ) # 更新多条 db.集合.updateMany( <query>, # update的查询条件,一般写法:{"属性":{条件:值}} <update>, # update的对象,一般写法 { $set:{"属性":"值"} } 或者 { $inc:{"属性":"值"} } { upsert: <boolean>, # 可选参数,如果文档不存在,是否插入objNew, true为插入,默认是false,不插入 multi: <boolean>, # 可选参数,是否把满足条件的所有数据全部更新 writeConcern: <document> # 可选参数,抛出异常的级别。 } )
update修改器
操作 | 语法 | |
---|---|---|
$inc |
db.集合.update({<key1>:<val1>},{$inc:{<key2>:<val2>}}) |
更新key1=val1的文档中key2的值为val2,类似python的递增递减 |
$set |
db.集合.update({<key1>:<val>}, {$set:{<key2>:<val2>}}) |
更新key1=val1的文档中key2的值为val2,如果key2不存在则新增对应键值对 |
$unset |
db.集合.update({<key1>:<val>}, {$unset:{<key2>:<val2>}}) |
移除key1=val1的文档中key2=val2这个键值对 |
$push |
db.集合.update({<key1>:<val>}, {$push:{<key2>:<val2>}}) |
给key1=val1的文档中key2列表增加一个数组成员val2。 key2必须是数组 |
$pull |
db.集合.update({<key1>:<val>}, {$pull:{<key2>:<val2>}}) |
与push相反,给key1=val1的文档中key2列表删除指定成员val2 |
$pop |
db.集合.update({<key1>:<val>}, {$pop:{<key2>:<val2>}}) |
给key1=val1的文档中key2列表移除第一个或最后一个成员。 val2只能是1(最后面)或-1(最前面),与python相反 |
查
# 直接显示查询的所有 # 获取一条 db.集合.findOne( <query>, # 查询条件 { <key>: 0, # 隐藏指定字段,例如:"_id":0, <key>: 1, # 显示指定字段,例如:"title":1, .... } ) # 获取多条 db.集合.find( <query>, # 查询条件 { <key>: 0, # 隐藏指定字段,例如:"_id":0, <key>: 1, # 显示指定字段,例如:"title":1, .... } ) # 以易读的方式来格式化显示读取到的数据 db.col.find().pretty()
比较运算
操作 | 格式 | 范例 | SQL中的类似语句 |
---|---|---|---|
等于 | {<key>:<val> } {<key>:{$eq:<val>}} |
db.集合.find({"name":"xiaoming"}) |
where name = 'xiaoming' |
小于 | {<key>:{$lt:<val>}} |
db.集合.find({"age":{$lt:17}}) |
where age < 17 |
小于或等于 | {<key>:{$lte:<val>}} |
db.集合.find({"age":{$lte:17}}) |
where age <= 17 |
大于 | {<key>:{$gt:<val>}} |
db.集合.find({"age":{$gt:17}}) |
where age > 17 |
大于或等于 | {<key>:{$gte:<val>}} |
db.集合.find({"age":{$gte:17}}) |
where age >= 17 |
不等于 | {<key>:{$ne:<val>}} |
db.集合.find({"age":{$ne:17}}) |
where age != 17 |
包含 | {<key>:{$in:<val>}} |
db.集合.find({"age":{$in:[1,2,3]}}) |
where age in (1,2,3) |
终端运行效果
db.my_friend.find({"name":{$eq:"xiaohong"}}).pretty() db.my_friend.find({"age":{$gt:15}}).pretty()
逻辑运算
操作 | 格式 | 语法 |
---|---|---|
$and |
{<key>:<val>,<key>:<val>,...} |
db.集合.find({key1:value1, key2:value2}) |
$or |
{$or: [{<key>: <val>}, {<key>:<val>}]} |
db.集合.find({$or: [{key1: value1}, {key2:value2}]}) |
$and 和$or |
{<key>:<val>, $or: [{<key>: <val>}, {<key>:<val>}]} {$and:[{$or:[{<key>:<val>},..]},$or:[{<key>:<val>},..]}]} |
db.集合.find({key1:value1, $or: [{key1: value1}, {key2:value2}]}) |
$not | {<key>:{$not:{<$运算符>:<val>}}} |
$not 操作符不支持`$regex 正则表达式操作 |
其他运算符
操作 | 格式 | 语法 | 说明 |
---|---|---|---|
$type | {<key>:{$type: <datetype>}} |
db.集合.find({"name":{$type:'string'}}) |
匹配指定键是指定数据类型的文档 |
$exists | {<key>:{$exists:<bool>} |
db.集合.find({"title":{$exists:true}}) |
匹配具有指定键的文档 |
$regex | { <key>:/模式/<修正符>} {<key>:{$regex:/模式/<修正符>}} |
db.集合.find({"name":{$regex:/张$/}}) |
按正则匹配 |
排序显示
db.集合.find().sort({<key>:1}) # 升序,默认为升序 db.集合.find().sort({<key>:-1}) # 倒序,
字段投影
find()方法默认将返回文档的所有数据,但是可以通过设置`find()`的第二个参数projection,设置值查询部分数据。 语法: # 获取一条 db.集合.findOne( <query>, # 查询条件 { <key>: 0, # 隐藏指定字段,例如:"_id":0, <key>: 1, # 显示指定字段,例如:"title":1, .... } ) # 获取多条 db.集合.find( <query>, # 查询条件 { <key>: 0, # 隐藏指定字段,例如:"_id":0, <key>: 1, # 显示指定字段,例如:"title":1, .... } )
PyMongo
安装
pip install pymongo
数据库连接
import pymongo # 无密码连接 mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/") # 密码连接 import pymongo from urllib import parse username = parse.quote_plus('bajie') # 对用户名进行编码 password = parse.quote_plus('1') # 对密码进行编码 database = parse.quote_plus("mofang") # 数据库名称 host = "127.0.0.1" # ip port = "27017" # 端口号 mongo = pymongo.MongoClient(f"mongodb://{username}:{password}@{host}:{port}/{database}") # 登录数据库mofang链接对象 db = mongo["mofang"] # 切换到mofang数据库 table = db["t_user"] # 创建表对象 print(mongo.database_names()) # 打印当前链接对象所拥有的库列表
集合操作
mongo = pymongo.MongoClient(f"mongodb://{username}:{password}@{host}:{port}/{database}") # 登录数据库mofang链接对象 db = mongo["mofang"] # 切换到mofang数据库 t_user = db["t_user"] # 创建表对象 db.collection_names() # 打印集合列表 db["t_user"].drop() # 删除表 db.drop_collection("t_user") # 删除表
文档操作
增
tb = db["t_book"] document = { "name": "xiaoming", "mobile": "13012345678","age":16,"sex":True} ret = tb.insert(document) # 增加一条记录,返回id值 data_list = [ { "name": "xiaobai", "mobile": "13322345678","age":16,"sex":False}, { "name": "xiaohei", "mobile": "13322345678","age":20,"sex":True}, { "name": "xiaohong", "mobile": "13322345678","age":13,"sex":False}, { "name": "xiaolan", "mobile": "13322345678","age":17,"sex":True}, { "name": "xiaolv", "mobile": "13322345678","age":17,"sex":True}, { "name": "xiaolong", "mobile": "13322345678","age":16,"sex":False}, { "name": "xiaofei", "mobile": "13322345678","age":18,"sex":True}, ] ret = tb.insert_many(data_list) # 增加多条记录,返回结果对象
删
query = {"age":1} ret = tb.delete_one(query) # 删除一个文档,返回结果对象 query = { "mobile": {"$regex": "^130"} } ret = my_collection.delete_many(query) query = { "mobile": {"$regex": "^130"} } ret = tb.delete_many(query) # 删除多个文档,返回结果对象 ret.deleted_count # 删除文档数量 query = {"name":"xiaobai"} document = tb.find_one_and_delete(query) # 查询一条数据出来并删除,返回一条数据,如果没有,则返回None
改
# 按条件修改字段(没有则添加) query = {"_id":1} upsert = {"$set":{"mobile":"999999"}} tb.update_one(query,upsert) """按条件累加/累减指定数值一个文档的指定数据""" query = { "name": "xiaofei" } upsert = { "$inc": { "age": -1 } } # 累减 ret = tb.update_one(query, upsert) """更新多条数据""" # 把所有以"133"开头的手机码号的文档,全部改成15012345678 query = { "mobile": {"$regex":"^150"} } upsert = { "$set": { "mobile": "18512345678" } } ret = my_collection.update_many(query, upsert)
查
document = tb.find_one() # 一条文档,查询不到则返回None document_list = tb.find() # 所有文档列表, 查询不到,返回空列表 for document in tb.find({},{"name":1}) # 只显示name字段 # 条件查询 query = {"age":18} document_list = tb.find(query) for document in document_list: print(document) # 比较运算符的使用 query = {"age":{"$gt":18}} document_list = tb.find(query) for document in document_list: print(document) # 排序(单字段) query = {"age":{"$gt":5}} document_list = tb.find(query).sort("age",-1) for document in document_list: print(document) # 排序(多字段) query = {"age":{"$gt":5}} document_list = tb.find(query).sort([("age",-1),("name",1)]) for document in document_list: print(document) # 限制查询结果数量 query = {"age":{"$gt":5}} document_list = tb.find(query).sort([("age",-1),("name",1)]).limit(3) for document in document_list: print(document)