MongoDB 数据库

精选 MongoDB 数据库 常用指令与核心速查备忘单,涵盖高频用法、配置参数与实用技巧。

#增删改查操作 (CRUD)

#插入数据 (Create)

db.coll.insertOne({name: "Max"})
db.coll.insertMany([{name: "Max"}, {name:"Alex"}]) // 有序批量插入 (ordered bulk insert)
db.coll.insertMany([{name: "Max"}, {name:"Alex"}], {ordered: false}) // 无序批量插入 (unordered bulk insert)
db.coll.insertOne({date: ISODate()})
db.coll.insertMany({name: "Max"}, {"writeConcern": {"w": "majority", "wtimeout": 5000}})

#删除数据 (Delete)

db.coll.deleteOne({name: "Max"})
db.coll.deleteMany( $and: [{name: "Max"}, {justOne: true}]) // 删除同时满足两个条件的文档记录
db.coll.deleteMany( $or: [{name: "Max"}, {justOne: true}])  // 删除满足任意条件的文档记录
db.coll.deleteMany({}) // 警告!将删除集合内的所有文档记录,但保留集合本身及其索引定义
db.coll.deleteMany({name: "Max"}, {"writeConcern": {"w": "majority", "wtimeout": 5000}})
db.coll.findOneAndDelete({"name": "Max"})

#更新数据 (Update)

db.coll.updateMany({"_id": 1}, {$set: {"year": 2016}}) // 警告!将替换更新所有 _id=1 的文档字段
db.coll.updateOne({"_id": 1}, {$set: {"year": 2016, name: "Max"}})
db.coll.updateOne({"_id": 1}, {$unset: {"year": 1}})
db.coll.updateOne({"_id": 1}, {$rename: {"year": "date"} })
db.coll.updateOne({"_id": 1}, {$inc: {"year": 5}})
db.coll.updateOne({"_id": 1}, {$mul: {price: 2}})
db.coll.updateOne({"_id": 1}, {$min: {"imdb": 5}})
db.coll.updateOne({"_id": 1}, {$max: {"imdb": 8}})
db.coll.updateMany({"_id": {$lt: 10}}, {$set: {"lastModified": ISODate()}})

#数组更新修改 (Array)

db.coll.updateOne({"_id": 1}, {$push :{"array": 1}})
db.coll.updateOne({"_id": 1}, {$pull :{"array": 1}})
db.coll.updateOne({"_id": 1}, {$addToSet :{"array": 2}})
db.coll.updateOne({"_id": 1}, {$pop: {"array": 1}})  // 弹出删除数组最后一个元素
db.coll.updateOne({"_id": 1}, {$pop: {"array": -1}}) // 弹出删除数组第一个元素
db.coll.updateOne({"_id": 1}, {$pullAll: {"array" :[3, 4, 5]}})
db.coll.updateOne({"_id": 1}, {$push: {scores: {$each: [90, 92, 85]}}})
db.coll.updateOne({"_id": 1, "grades": 80}, {$set: {"grades.$": 82}})
db.coll.updateMany({}, {$inc: {"grades.$[]": 10}})
db.coll.updateMany({}, {$set: {"grades.$[element]": 100}}, {arrayFilters: [{"element": {$gte: 100}}]})

#批量更新多行 (Update many)

db.coll.updateMany({"year": 1999}, {$set: {"decade": "90's"}})

#查找并更新 (FindOneAndUpdate)

db.coll.findOneAndUpdate({"name": "Max"}, {$inc: {"points": 5}}, {returnNewDocument: true})

#存在即更新/不存在则插入 (Upsert)

db.coll.updateOne({"_id": 1}, {$set: {item: "apple"}, $setOnInsert: {defaultQty: 100}}, {upsert: true})

#文档替换 (Replace)

db.coll.replaceOne({"name": "Max"}, {"firstname": "Maxime", "surname": "Beugnet"})

#写安全级别设置 (Write concern)

db.coll.updateMany({}, {$set: {"x": 1}}, {"writeConcern": {"w": "majority", "wtimeout": 5000}})

#查询文档 (Find)

db.coll.findOne() // 返回单条匹配的文档记录
db.coll.find()    // 返回游标 Cursor - 默认展示前 20 条结果,输入 "it" 继续分页查看
db.coll.find().pretty()
db.coll.find({name: "Max", age: 32}) // 隐式逻辑 "AND" 条件查询
db.coll.find({date: ISODate("2020-09-25T13:57:17.180Z")})
db.coll.find({name: "Max", age: 32}).explain("executionStats") // 执行计划分析 (或 queryPlanner / allPlansExecution)
db.coll.distinct("name")

#统计计数 (Count)

db.coll.estimatedDocumentCount()  // 基于集合元数据估算文档总数
db.coll.countDocuments({age: 32}) // 聚合管道精确统计文档数量

#比较运算符查询 (Comparison)

db.coll.find({"year": {$gt: 1970}})
db.coll.find({"year": {$gte: 1970}})
db.coll.find({"year": {$lt: 1970}})
db.coll.find({"year": {$lte: 1970}})
db.coll.find({"year": {$ne: 1970}})
db.coll.find({"year": {$in: [1958, 1959]}})
db.coll.find({"year": {$nin: [1958, 1959]}})

#逻辑运算符查询 (Logical)

db.coll.find({name:{$not: {$eq: "Max"}}})
db.coll.find({$or: [{"year" : 1958}, {"year" : 1959}]})
db.coll.find({$nor: [{price: 1.99}, {sale: true}]})
db.coll.find({
$and: [
    {$or: [{qty: {$lt :10}}, {qty :{$gt: 50}}]},
{$or: [{sale: true}, {price: {$lt: 5 }}]}
]
})

#元素查询运算符 (Element)

db.coll.find({name: {$exists: true}})
db.coll.find({"zipCode": {$type: 2 }})
db.coll.find({"zipCode": {$type: "string"}})

#聚合管道 (Aggregation Pipeline)

db.coll.aggregate([
{$match: {status: "A"}},
{$group: {_id: "$cust_id", total: {$sum: "$amount"}}},
{$sort: {total: -1}}
])
db.coll.find({$text: {$search: "cake"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})

#正则表达式查询 (Regex)

db.coll.find({name: /^Max/}) // 正则表达式匹配:以字母 "M" 开头
db.coll.find({name: /^Max$/i}) // 不区分大小写的正则表达式匹配

#数组查询 (Array)

db.coll.find({tags: {$all: ["Realm", "Charts"]}})
db.coll.find({field: {$size: 2}}) // 无法直接建立索引 - 建议单独存储数组长度字段并随之更新
db.coll.find({results: {$elemMatch: {product: "xyz", score: {$gte: 8}}}})

#字段投影过滤 (Projections)

db.coll.find({"x": 1}, {"actors": 1}) // 返回 actors 字段与 _id 字段
db.coll.find({"x": 1}, {"actors": 1, "_id": 0}) // 仅返回 actors 字段 (隐藏 _id)
db.coll.find({"x": 1}, {"actors": 0, "summary": 0}) // 返回除了 actors 与 summary 之外的所有字段

#排序、跳过与分页限制 (Sort, skip, limit)

db.coll.find({}).sort({"year": 1, "rating": -1}).skip(10).limit(3)

#读安全级别 (Read Concern)

db.coll.find().readConcern("majority")

#数据库与集合管理 (Databases and Collections)

#删除操作 (Drop)

db.coll.drop()    // 删除集合及其对应的所有索引定义
db.dropDatabase() // 警告!请务必再三确认当前*不在*生产环境 Cluster 上!

#创建带 Schema 校验的集合 (Create Collection)

db.createCollection("contacts", {
   validator: {$jsonSchema: {
      bsonType: "object",
      必填: ["phone"],
      properties: {
         phone: {
            bsonType: "string",
            description: "必须为字符串类型且为必填项"
         },
         email: {
            bsonType: "string",
            pattern: "@mongodb\.com$",
            description: "必须为字符串且符合正则表达式邮箱格式"
         },
         status: {
            enum: [ "Unknown", "Incomplete" ],
            description: "必须为预设枚举值之一"
         }
      }
   }}
})

#集合状态与辅助函数 (Other Collection Functions)

db.coll.stats()
db.coll.storageSize()
db.coll.totalIndexSize()
db.coll.totalSize()
db.coll.validate({full: true})
db.coll.renameCollection("new_coll", true) // 第二个参数为 true 表示若目标集合存在则直接覆盖删除

#索引管理 (Indexes)

#索引基础 (Basics)

查看索引列表 (List)

db.coll.getIndexes()
db.coll.getIndexKeys()

删除指定索引 (Drop Indexes)

db.coll.dropIndex("name_1")

隐藏与取消隐藏索引 (Hide/Unhide Indexes)

db.coll.hideIndex("name_1")
db.coll.unhideIndex("name_1")

#创建索引 (Create Indexes)

// 索引类型 (Index Types)
db.coll.createIndex({"name": 1})                // 单字段索引
db.coll.createIndex({"name": 1, "date": 1})     // 复合索引
db.coll.createIndex({foo: "text", bar: "text"}) // 全文索引
db.coll.createIndex({"$**": "text"})            // 通配符全文索引
db.coll.createIndex({"userMetadata.$**": 1})    // 通配符索引
db.coll.createIndex({"loc": "2d"})              // 2D 平面地理索引
db.coll.createIndex({"loc": "2dsphere"})        // 2DSphere 球面地理索引
db.coll.createIndex({"_id": "hashed"})          // 哈希索引

// 索引参数选项 (Index Options)
db.coll.createIndex({"lastModifiedDate": 1}, {expireAfterSeconds: 3600})      // TTL 自动过期索引
db.coll.createIndex({"name": 1}, {unique: true})                              // 唯一索引
db.coll.createIndex({"name": 1}, {partialFilterExpression: {age: {$gt: 18}}}) // 部分条件索引
db.coll.createIndex({"name": 1}, {collation: {locale: 'en', strength: 1}})    // 不区分大小写的排序规则索引
db.coll.createIndex({"name": 1 }, {sparse: true})                             // 稀疏索引

#其他实用管理工具

#运维管理常用命令 (Handy commands)

use admin
db.createUser({"user": "root", "pwd": passwordPrompt(), "roles": ["root"]})
db.dropUser("root")
db.auth( "user", passwordPrompt() )

use test
db.getSiblingDB("dbname")
db.currentOp()
db.killOp(123) // opid 操作 ID

db.fsyncLock()
db.fsyncUnlock()

db.getCollectionNames()
db.getCollectionInfos()
db.printCollectionStats()
db.stats()

db.getReplicationInfo()
db.printReplicationInfo()
db.isMaster()
db.hostInfo()
db.printShardingStatus()
db.shutdownServer()
db.serverStatus()

db.setSlaveOk()
db.getSlaveOk()

db.getProfilingLevel()
db.getProfilingStatus()
db.setProfilingLevel(1, 200) // 0 == 关闭, 1 == 开启并记录慢查询, 2 == 开启记录所有查询

db.enableFreeMonitoring()
db.disableFreeMonitoring()
db.getFreeMonitoringStatus()

db.createView("viewName", "sourceColl", [{$project:{department: 1}}])

#副本集配置管理 (Replica Set)

rs.status()
rs.initiate({"_id": "replicaTest",
  members: [
    { _id: 0, host: "127.0.0.1:27017" },
    { _id: 1, host: "127.0.0.1:27018" },
    { _id: 2, host: "127.0.0.1:27019", arbiterOnly:true }]
})
rs.add("mongodbd1.example.net:27017")
rs.addArb("mongodbd2.example.net:27017")
rs.remove("mongodbd1.example.net:27017")
rs.conf()
rs.isMaster()
rs.printReplicationInfo()
rs.printSlaveReplicationInfo()
rs.reconfig(<valid_conf>)
rs.slaveOk()
rs.stepDown(20, 5) // (stepDownSecs, secondaryCatchUpPeriodSecs)

#分片集群管理 (Sharded Cluster)

sh.status()
sh.addShard("rs1/mongodbd1.example.net:27017")
sh.shardCollection("mydb.coll", {zipcode: 1})

sh.moveChunk("mydb.coll", { zipcode: "53187" }, "shard0019")
sh.splitAt("mydb.coll", {x: 70})
sh.splitFind("mydb.coll", {x: 70})
sh.disableAutoSplit()
sh.enableAutoSplit()

sh.startBalancer()
sh.stopBalancer()
sh.disableBalancing("mydb.coll")
sh.enableBalancing("mydb.coll")
sh.getBalancerState()
sh.setBalancerState(true/false)
sh.isBalancerRunning()

sh.addTagRange("mydb.coll", {state: "NY", zip: MinKey }, { state: "NY", zip: MaxKey }, "NY")
sh.removeTagRange("mydb.coll", {state: "NY", zip: MinKey }, { state: "NY", zip: MaxKey }, "NY")
sh.addShardTag("shard0000", "NYC")
sh.removeShardTag("shard0000", "NYC")

sh.addShardToZone("shard0000", "JFK")
sh.removeShardFromZone("shard0000", "NYC")
sh.removeRangeFromZone("mydb.coll", {a: 1, b: 1}, {a: 10, b: 10})

#变更流监听 (Change Streams)

watchCursor = db.coll.watch( [ { $match : {"operationType" : "insert" } } ] )

while (!watchCursor.isExhausted()){
   if (watchCursor.hasNext()){
      print(tojson(watchCursor.next()));
   }
}