常见操作
本文以 8.0 语法为准
# 数据库
# 列表
show dbs
// or
show databases
自带数据库:
admin
:管理用户权限local
:永不会被复制,可以用来存储限于本地单台服务器的任意集合config
:保存分片的相关信息
# 创建(选择)
use
字面上为选中数据库,但如数据库不存在,则会先创建再选择。
use 表名
表名规范:
- 不能是空串
- 不得含有
空格 . $ / \ \0(空字符)
- 应全部小写
- 最多 64Byte
Note
如果只是创建了,但没有存储集合(即空库),在列表中是不显示的(没有持久化)。
# 当前库
db
# 删除
db.dropDatabase()
# 集合
# 列表
show collections
# 创建
不常用,在创建文档时,如集合不存在会自动创建。
db.createCollection(集合名称)
# 删除
db.集合名称.drop()
# 文档
# 查询 - 基本
// 查询所有
db.集合名称.find()
// 条件查询,返回列表
db.集合名称.find({item:"card"})
// 条件查询,返回第一个
db.集合名称.findOne({item:"card"})
// 返回部分字段,显示item字段,_id默认显示,如需不显示需明确不显示(0)
db.集合名称.find({item:"card"},{item:1,_id:0})
查询条件语法参考:查询文档 - MongoDB 手册 (opens new window)
# 查询 - 分页
# 统计记录数
db.集合名称.count(查询条件)
# 分页列表
db.集合名称.find(查询条件).limit(页码).skip(偏移量)
db.集合名称.find(查询条件).limit(2).skip(2) // 返回2条,跳过前2条(即第2页数据)
# 排序
// key:排序字段
// value:1=升序 -1=降序
db.集合名称.find().sort({key:1})
# 查询 - 复杂条件
# 正则(模糊查询)
db.集合名称.find({字段:/正则表达式/})
# 比较
db.集合名称.find({字段:{$gt.value}}) // >
db.集合名称.find({字段:{$lt.value}}) // <
db.集合名称.find({字段:{$gte.value}}) // >=
db.集合名称.find({字段:{$lte.value}}) // <=
db.集合名称.find({字段:{$ne.value}}) // <>
# 包含 (in)
// 包含
db.集合名称.find({字段:{$in:[value1,value2]}})
// 不包含
db.集合名称.find({字段:{$nin:[value1,value2]}})
# 连接 (and、or)
// and
db.集合名称.find({$and:[条件1,条件2]})
// or
db.集合名称.find({$or:[条件1,条件2]})
# 插入 - 一个
Note
如插入的集合不存在,则会自动创建,再插入
// 随机id
db.集合名称.insertOne( { item: "card", qty: 15 } );
// 自定义id
db.集合名称.insertOne( { _id: 10, item: "box", qty: 20 } );
- 如果插入的对象中没有
_id
字段,操作返回的insertedId
字段为改对象的_id
- 可在创建时携带
_id
字段
# 插入 - 批量
// 随机id
db.集合名称.insertMany( [
{ item: "card", qty: 15 },
{ item: "envelope", qty: 20 },
{ item: "stamps" , qty: 30 }
] );
// 自定义id:略,与插入操作一致。
- 未指定 id 时,操作返回的
insertedIds
数组字段返回对应的对象 id
# 部分更新 - 一个
参考:字段更新操作符 - MongoDB 手册 (opens new window) 只更新符合条件的第一条数据
db.集合名称.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true },
$inc: { quantity: -2, "metrics.orders": 1 }
}
)
- 参数 1:匹配条件
- 参数 2:
$set
:要更新的字段和更新后的值$currentDate
:将lastModified
字段的值更新为当前日期,如没有则会创建$inc
:值自增,类似quantity = quantity - 2
,
# 部分更新 - 批量
使用与【单个更新】相同,区别为受影响的文档数不同
db.集合名称.updateMany(
{ "qty": { $lt: 50 } },
{
$set: { "size.uom": "in", status: "P" },
$currentDate: { lastModified: true }
}
)
# 覆盖更新 - 一个
db.集合名称.replaceOne(
{ item: "paper" },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)
将符合参数 1 的第一个文档,除 _id
字段外,内容改为为参数 2。
# 删除 - 一个
db.集合名称.deleteOne(查询条件)
// 删除符合条件的第一个文档
db.集合名称.deleteOne( { status: "D" } )
# 删除 - 批量
// 删除符合条件的所有文档
db.集合名称.deleteMany( { status: "D" } )
// 删除集合所有文档
db.集合名称.deleteMany({ status : "A" })
# 查询 - 聚合统计
聚合管道 - MongoDB 手册 (opens new window)
# $addFields 新增字段
# $dateTrunc 截断时间
$dateTrunc(聚合) - MongoDB 手册 (opens new window) 将一个时间的某部分(年、季度、星期、月份……)后的数据抹掉。
$dateTrunc: {
// 要处理的字段
date: "$orderDate",
// 截断的单位
unit: "week",
// 单位的数量,如这里为2周
binSize: 2,
// 用于 $dateTrunc 计算的时区,如果传入的是 UTC 时间,会报错
timezone: "America/Los_Angeles",
// 一周的开始。当单位为 week 时使用。默认为 Sunday。
startOfWeek: "Monday"
}
示例:
db.transactions.aggregate([
// 步骤1
{
// 添加字段
$addFields: {
// 添加一个date
date: {
$dateFromString: {
dateString: "$timestamp"
}
}
},
},
{
// 使用 $dateTrunc 按天进行日期截断
$group: {
_id: {
day: {
$dateTrunc: {
date: "$date",
unit: "day",
timezone: "Asia/Shanghai" // 显示的ISO时间10-27 16:00,即为上海时间10:28 00:00
}
}
},
totalValue: { $sum: {$divide: [{ $toDouble: "$value" }, 500000000000000000]} } // 假设要统计 value 字段的总和
}
},
{
// 按日期排序
$sort: { "_id.day": 1 }
}
])
# 索引
# 列表
默认创建了 _id
索引
db.集合名称.getIndexes()
v
:索引引擎版本key
:索引字段,1 为升序name
:索引名称ns
:
# 创建
参考:db.collection.createIndex () — MongoDB 手册 (opens new window)
db.集合名称.createIndex( { name : -1 }, {name:"idx_name"})
- 参数 1:对象中的 key 为索引字段,value=
1
时升序,-1
时倒序,多个 key 即为复合索引。 - 参数 2:
unique
:创建唯一索引,默认值为false
name
:索引名称,未指定时,按索引字段的名称和排序顺序生成索引名称
# 删除
db.集合名称.dropIndex(index)
// 按索引名称删除
db.集合名称.dropIndex("idx_name")
// 按key删除
db.集合名称.dropIndex({ name : -1 })
# 索引优化(Explain)
// 查询条件后面加.explain(options)
db.集合名称.find(...).explain()
# 其他
# 异常捕获
MongoDB 没有事务回滚操作,但可以通过捕获异常来得知哪些操作失败了,语法跟 JavaScript 完全一样。
try {
db.products.insertMany( [
{ item: "card", qty: 15 },
{ item: "envelope", qty: 20 },
{ item: "stamps" , qty: 30 }
] );
} catch (e) {
print (e);
}
上次更新: 2024/10/30, 16:33:46