目录
一、数据库操作
// 查看所有数据库
show dbs
// 切换/创建数据库(插入数据时正式创建)
use database_name
// 查看当前数据库
db
db.getName()
// 删除数据库(需先切换到目标库)
db.dropDatabase()
// 显示数据库中的用户
show users
二、集合(表)操作
// 集合集合的隐式创建:当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
// 显式创建
db.createCollection("myCollec")
db.createCollection("users", {
capped: true, // 固定集合
size: 5242880, // 字节大小(5MB)
max: 5000 // 最大文档数
})
// 查看所有集合
show collections
show tables
// 删除集合,成功删除集合将返回true,否则返回false
db.collection_name.drop()
// 集合统计信息
db.collection_name.stats()
// 查询当前集合的数据条数
db.collection_name.count()
// 获取集合大小
db.users.dataSize()
db.getCollection("account") #得到指定名称的聚集集合(table)
db.getCollectionNames() #得到当前db的所有聚集集合
db.printCollectionStats() #显示当前db所有聚集索引的状态
三、文档(记录)CRUD 操作
1、插入文档
// 插入单条
db.users.insertOne({
name: "Alice",
age: 28,
email: "alice@example.com",
tags: ["developer", "python"]
})
// 插入多条
db.users.insertMany([
{ name: "Bob", age: 32, status: "active" },
{ name: "Charlie", age: 25, status: "pending" }
])
2、查询文档
// 查询所有 相当于 select * from users
db.users.find()
// 条件查询
db.users.find({ age: { $gt: 30 } }) // 年龄>30
db.users.find({ status: "active" }) // 状态为active
db.userInfo.find({name: /mongo/}) // select * from userInfo where name like ‘%mongo%’
db.userInfo.find({name: /^mongo/}) //select * from userInfo where name like ‘mongo%’
// 查询指定列
db.userInfo.find({}, {name: 1, age: 1}) //select name, age from userInfo
// AND 查询 pretty格式化显示结果
db.users.find({ age: 28, name: "Alice" }).pretty()
// OR 查询
db.users.find({ $or: [{ age: 28 }, { status: "pending" }] })
// NOT 查询
db.users.find({ age: {$not:{$lt:18}} }) //年龄!<18
// 投影(选择返回字段)
db.users.find({}, { name: 1, email: 1 }) // 1=包含, 0=排除
// 排序
db.users.find().sort({ age: -1 }) // -1=降序, 1=升序
// 分页
db.users.find().skip(10).limit(5) // 跳过10条,取5条
3、更新文档
update方法:db.collection.update(<query>, <update>, {upsert: <boolean>, multi: <boolean>,writeConcern: <document>})
query
是查询条件,类似sql update查询内where后面的;
update
是更新内容,也可以理解为sql update查询内set后面的;
upsert
可选,表示如果不存在满足条件的文档,是否插入新文档(默认为false
);
multi
可选,表示是否更新所有满足条件的文档(默认为false
,只更新第一个);writeConcern 可选,⽤来指定mongod对写操作的回执⾏为⽐如写的⾏为是否需要确认
writeConcern
包括以下字段: { w: <value>, j: <boolean>, wtimeout: <number> }
w: 指定写操作传播到的成员数量⽐如: w=1(默认):则要求得到写操作已经传播到独⽴的 Mongod 实例或副本集的 primary 成员的确认w=0:则不要求确认写操作,可能会返回socket exceptions 和 networking errorsw="majority":要求得到写操作已经传播到⼤多数具有存储数据具有投票的(data-bearing voting )成员(也就是 members[n].votes 值⼤于 0 的成员)的确认j: 要求得到 Mongodb 的写操作已经写到硬盘⽇志的确认⽐如: j=true:要求得到Mongodb(w指定的实例个数 ) 的写操作已经写到硬盘⽇志的确认。 j=true 本身并不保证因为副本集故障⽽不会回滚。wtimeout:指定 write concern 的时间限制,只适⽤于 w>1 的情况wtimeout在超过指定时间后写操作会返回 error ,即使写操作最后执⾏成功,当这些写操作返回时, MongoDB 不会撤消在wtimeout 时间限制之前执⾏成功的数据修改。如果未指定wtimeout 选项且未指定 write concern 级别,则写⼊操作将⽆限期阻⽌。 指定 wtimeout 值为 0 等同于没有wtimeout 选项。
// 更新单条
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 29 }, $push: { tags: "mongodb" } }
)
// 更新多条
db.users.updateMany(
{ status: "pending" },
{ $set: { status: "active" } }
)
// 替换文档
db.users.replaceOne(
{ name: "Bob" },
{ full_name: "Bob Smith", department: "IT" }
)
4、删除文档
db.collection.remove(query, {justOne: <boolean>,writeConcern: <document>})
query : (可选)删除的⽂档的条件。justOne : (可选)如果设为 true 或 1 ,则只删除⼀个⽂档,如果不设置该参数,或使⽤默认值 false ,则删除所有匹配条件的⽂档。writeConcern : (可选)⽤来指定 mongod 对写操作的回执⾏为。
// 删除单条
db.users.deleteOne({ name: "Charlie" })
// 删除多条
db.users.deleteMany({ status: "inactive" })
四、聚合操作
1、单目的聚合操作
// 去重 相当于:select distict name from userInfo
db.userInfo.distinct("name")
// 计数 相当于:select count(sex) from userInfo select * from userInfo
db.userInfo.find({sex: {$exists: true}}).count()
db.userInfo.find({}).count()
2、聚合管道
MongoDB
中聚合
(aggregate)
主要⽤于统计数据
(
诸如统计平均值
,
求和等
)
,并返回计算后的数据结果。
MongoDB
的聚合管道将
MongoDB
⽂档在⼀个管道处理完毕后将结果传递给下⼀个管道处理。管道操作是可以重复的。
常用操作:
- $group:将集合中的⽂档分组,可⽤于统计结果。
- $project:修改输⼊⽂档的结构。可以⽤来重命名、增加或删除域,也可以⽤于创建计算结果以及嵌套⽂档。
- $match:⽤于过滤数据,只输出符合条件的⽂档。$match使⽤MongoDB的标准查询操作。
- $limit:⽤来限制MongoDB聚合管道返回的⽂档数。
- $skip:在聚合管道中跳过指定数量的⽂档,并返回余下的⽂档。
- $sort:将输⼊⽂档排序后输出。
- $geoNear:输出接近某⼀地理位置的有序⽂档。
常用表达式:

db.orders.aggregate([
// 阶段1:匹配条件
{ $match: { status: "completed" } },
// 阶段2:按用户分组计算总金额
{ $group: {
_id: "$user_id",
total: { $sum: "$amount" }
}
},
// 阶段3:结果排序
{ $sort: { total: -1 } },
// 阶段4:限制输出
{ $limit: 10 }
])
db.lg_resume_preview.aggregate(
[{$group : {_id: "$city", avgSal:{$avg:"$expectSalary"}}}, //按城市分组计算平均金额
{$project : {city: "$city", salary : "$avgSal"}} //结果重命名
])
db.lg_resume_preview.aggregate(
[{$group:{_id: "$city",count:{$sum : 1}}}, //按城市分组统计数量
{$match:{count:{$gt:1}}} //过滤出计数>1的数据
])
3、MapReduce编程
管道速度快于MapReduce,MapReduce的优势在于可以在多台Server上并行执行最终合并。
MongoDB不允许管道
的单个聚合操作占⽤过多的系统内存,如果⼀个聚合操作消耗20%
以上的内存,那么MongoDB
直接停⽌操作,并向客户端输出错误消息。
db.collection.mapReduce(
function() {emit(key,value);}, //map 函数
function(key,values) {return reduceFunction}, //reduce 函数
{
out: collection,
query: document,
sort: document,
limit: number,
finalize: <function>,
verbose: <boolean>
}
)
使⽤
MapReduce
要实现两个函数
Map
函数和
Reduce
函数
,Map
函数调⽤
emit(key, value),
遍历
collection
中所有的记录,
将
key
与
value
传递给
Reduce
函数进⾏处理。
参数说明:
- map:是JavaScript 函数,负责将每⼀个输⼊⽂档转换为零或多个⽂档,⽣成键值对序列,作为 reduce 函数参数
- reduce:是JavaScript 函数,对map操作的输出做合并的化简的操作(将key-value变成key-values,也就是把values数组变成⼀个单⼀的值value)
- out:统计结果存放集合
- query: ⼀个筛选条件,只有满⾜条件的⽂档才会调⽤map函数。
- sort: 和limit结合的sort排序参数(也是在发往map函数前给⽂档排序),可以优化分组机制
- limit: 发往map函数的⽂档数量的上限(要是没有limit,单独使⽤sort的⽤处不⼤)
- finalize:可以对reduce输出结果再⼀次修改
- verbose:是否包括结果信息中的时间信息,默认为fasle
db.lg_resume_preview.mapReduce(
function() { emit(this.city,this.expectSalary); },
function(key, value) {return Array.avg(value)},
{
query:{expectSalary:{$gt: 15000}},
out:"cityAvgSal"
}
)
五、索引管理操作
// 创建单字段索引
db.users.createIndex({ email: 1 }) // 1=升序, -1=降序
// 创建复合索引
db.users.createIndex({ name: 1, age: -1 })
// 创建唯一索引
db.users.createIndex({ username: 1 }, { unique: true })
// 查看索引
db.users.getIndexes()
// 删除索引
db.users.dropIndex("email_1")
六、用户权限管理
// 切换到admin数据库
use admin
// 创建管理员
db.createUser({
user: "admin",
pwd: "s3cr3tP@ss",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
"clusterAdmin"
]
})
// 创建应用用户
db.createUser({
user: "app_user",
pwd: "appP@ss123",
roles: [ { role: "readWrite", db: "mydb" } ]
})
// 修改密码
db.changeUserPassword("app_user", "newP@ss456")
// 查看用户
db.getUsers()
// 删除用户
db.dropUser("old_user")
七、数据备份与恢复操作
# 备份整个数据库
mongodump --uri "mongodb://admin:s3cr3tP@ss@localhost:27017" --out /backup/
mongodump -h 127.0.0.1 -u用户名 -p密码 -o /home/dev/mongodb/
# 恢复数据库
mongorestore --uri "mongodb://admin:s3cr3tP@ss@localhost:27017" /backup/mydb/
# 备份单个数据库
mongodump --db mydb --out /backup/
mongodump --host mongodb1.example.net --port 27017 -u用户名 -p密码 --db mydbname --out /path/to/backup/
mongodump -h ip:端口 -uroot -p密码 -d 数据库 -o 路径
mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -o 文件存在路径
# 恢复单库
mongorestore --host mongodb2.example.net --port 27017 -u用户名 -p密码 --db mydbname /path/to/backup/mydbname/
mongorestore -h 127.0.0.1:27017 -u用户名 -p密码 -d 数据库 --dir /路径/数据库名/
#备份数据库某个集合
mongodump -uroot -p密码 -d 数据库 -c 集合名 -o 路径
mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 集合名 -o 文件存在路径
mongoexport --port 端口号 -d 库名 -c 表名 -o 备份文件路径.json
mongoexport --port 端口号 -d 库名 -c 表名 --type=csv -f 备份的字段 -o 备份文件路径.csv
#恢复某个集合 还原csv格式表时要加上–headerline参数,否则会将字段名也作为一条数据插入;–headerline和-f不能同时使用
mongoimport --port 26017 -d 要还原的库名-c 表名 备份文件路径.json
mongoimport --port 26017 -d 库名 -c 表名–type=csv --headerline 备份文件路径.csv
# 导出表中部分字段
mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 -f 字段 -q 条件导出 --csv -o 文件名
mongoexport -d tank -c users --csv -f uid,name,sex -o tank/users.csv #导出表中部分字段
mongoexport -d tank -c users -q '{uid:{$gt:1}}' -o tank/users.json #根据条件导出数据
#导入表部分字段
mongoimport -d tank -c users --upsert tank/users.dat #还原导出的表数据
mongoimport -d tank -c users --upsertFields uid,name,sex tank/users.dat #部分字段的表数据导入
mongoimport -d tank -c users --type csv --headerline --file tank/users.csv #还原csv文件
#加密后备份
mongodump -h ip:port -uroot -p密码 -d 数据库 --authenticationDatabase admin -o 路径
mongodump -uroot -p密码 -d 数据库 -c 集合名 --authenticationDatabase admin -o 路径
#恢复加密备份
mongorestore -uroot -p密码 -d wjTemp2 --authenticationDatabase admin --dir /root/mon_wjTemp/wjTemp/
八、脚本文件操作
// 执行JavaScript文件
load("scripts/mydata.js")
// 查看命令执行统计
db.runCommand({ serverStatus: 1 })
// 查看操作进程
db.currentOp()
// 终止操作
db.killOp(opid)
九、事务操作(MongoDB 4.0+)
// 开启会话
const session = db.getMongo().startSession()
// 开启事务
session.startTransaction()
try {
const users = session.getDatabase('mydb').users
const orders = session.getDatabase('mydb').orders
users.deleteOne({ _id: 123 }, { session })
orders.insertOne({ user: 123, items: [...] }, { session })
// 提交事务
session.commitTransaction()
} catch (error) {
// 回滚事务
session.abortTransaction()
} finally {
session.endSession()
}
十、地理空间查询
// 创建集合
db.createCollection("places")
// 创建2dsphere索引(地球球面模型:2dsphere;平面地图:2d)
db.places.createIndex({ location: "2dsphere" })
// 创建的数据 注意:经度在前(-180 到 180),纬度在后(-90 到 90)
db.places.insertOne({
name: "Alice",
location: { type: "Point", coordinates: [2.2945, 48.8584] }
})
// 查找5公里内的咖啡馆
db.places.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [currentLng, currentLat]
},
$maxDistance: 5000, // 最大距离(米)
$minDistance: 50 // 最小距离(可选)
}
},
category: "cafe"
})
// 聚合
db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [116.404, 39.915] },
distanceField: "distance", // 输出距离字段
maxDistance: 2000, // 最大距离(米)
spherical: true, // 球面计算
query: { type: "restaurant" } // 附加过滤条件
}
},
{ $sort: { distance: 1 } }, // 按距离排序
{ $limit: 10 } // 返回前10条
])