mongodb 常用操作

143 阅读1分钟

mongodb

command

mongo --quiet --port 27017 crm --eval 'db.user.find({"name":{$regex:/^go/}}).forEach(printjson)'

# user
use crm
db.createUser({
  user: "testuser",
  pwd: "test123",
  roles: [
    { role: "readWrite", db: "crm" },
    { role: "dbAdmin", db: "crm" }
  ]
})
db.auth("testuser", "test123")
db.dropUser("testuser")

use admin
db.createUser({user:"admin",pwd:"admin123",roles:["root"]})
db.createUser({
    user: 'mongouser',
    pwd: 'crm123',
    "roles" : [
        {"role":"dbAdminAnyDatabase","db":"admin"},
        {"role":"readWriteAnyDatabase","db":"admin"},
        {"role":"backup","db":"admin"},
        {"role":"restore","db":"admin"},
        {"role":"clusterAdmin","db":"admin"}
    ]
})

# restart the authentication after you configure the user
./mongod --dbpath ./data --logpath logs/mongo.log --bind_ip 0.0.0.0 --fork --auth
mongo admin --quiet -u admin -p admin123
mongo --host mongodb://admin:admin123@127.0.0.1:27017/crm?authSource=admin
mongo --host mongodb://admin:admin123@127.0.0.1:27017,127.0.0.2:27017/crm?authSource=admin
mongo --host mongodb://admin:admin123@127.0.0.1:27017/test?authSource=admin
mongo crm --quiet --host 127.0.0.1 --port 27017 -u testuser -p test123
mongo --host mongodb://testuser:test123@127.0.0.1:27017/crm?authSource=crm --quiet

# db
show dbs
use crm
db
db.user.insertOne({
    "name":"mongodb"
})
db.dropDatabase()

# collections
show collections
show tables
db.createCollection("user",{ capped: true, size: 5242880, max: 5000 })
db.user.insertOne({ name: "Alice", age: 30 })
db.user.find()
db.user.findOne()
db.user.drop()

# dbAdmin dbOwner
db.adminCommand({
  renameCollection: "crm.info",
  to: "crm.newinfo"
})

db.createCollection("info", {
  validator: { $jsonSchema: {
    bsonType: "object",
    required: ["name"],
    properties: {
      name: {
        bsonType: "string",
        description: "required"
      },
      email: {
        bsonType: "string",
        pattern: "^.+@.+$",
        description: "must be a vaild mailbox"
      }
    }
  }}
})

db.info.insertOne({
    "name":"mongodb",
    "age": 7,
    "email": "12345@qq.com"
})

# crud
db.info.insertOne({
    "name":"python"
})

db.info.insertMany([
    { "name":"golang","age": 5,"email": "golang@qq.com"},
    { "name":"c++","age": 10,"email": "c++@qq.com"}
]);

db.info.insertOne({
    "name":"python"
})

db.info.updateOne(
    { "name":"python"},
    { $set:{age:"12"} }
)

db.info.updateMany(
    { age: { $gt: 110 }},
    { $set: { name: "python" }}
)

db.info.replaceOne(
    {"name": "python"},
    {"name":"go","age":10}
)

db.info.deleteOne(
    {"name":"python"}
)

db.info.deleteMany(
    {"age":10}
)

db.info.findOneAndDelete(
    {"name":"mongodb"}
)

db.info.findOne()

db.info.find().pretty()

# $gt $gte $lt $lte $eq $ne $in $nin
db.info.find(
    {"age": { $gt: 3 }}
).pretty()

# $and $or $not #nor
db.info.find({
    $and: [
        { age: { $gt: 3 } },
        { name: "golang" }
    ]
});

# sort by desc
db.info.find().sort(
    { age: -1 }
);

# sort by asc
db.info.find().sort(
    { age: 1 }
);

db.info.find().limit(10);

db.info.find(
    {"name":{ $type: "string"}}
)

# regex
db.user.find({
    "name": { $regex: /^go/ }
    "city": { $regex: /shanghai$/ }
})
# regex neglect the case
db.user.find({
    "name": { $regex: /go/i }
})

# index
db.info.createIndex({ age: 1 });
db.info.createIndex({ age: -1 },{ name: "idx_age_desc"});
db.info.getIndexes()
db.info.totalIndexSize()
db.info.dropIndex("idx_age_desc")
db.info.dropIndex("age_1")
db.info.dropIndexes()

# aggregate
# select name, count(*) from info group by name
db.info.aggregate([{
    $group: { _id:"$name", total:{ $sum: 1}}
}])

# select name, avg("age") from info group by name
db.info.aggregate([{
    $group: { _id:"$name", total:{ $avg: "$age" }}
}])

backup and monitor

./mongodump --host 127.0.0.1 --port 27017 -d crm -o bak
./mongodump --host 127.0.0.1 --port 27017 -d crm -c user -o ./

./mongorestore -h 127.0.0.1:27017 -d crm --dir bak/crm
./mongorestore -h 127.0.0.1:27017 -d crm crm

 ./mongostat -h 127.0.0.1:27017
 ./mongotop -h 127.0.0.1:27017

## conn
db.serverStatus().uptime
db.serverStatus().version
db.serverStatus().mem
db.serverStatus().connections
db.serverStatus().opcounters
db.currentOp()
db.currentOp(true).inprog.forEach(function(op){ if(op.host){print(op.host)} })

use admin
db.runCommand({ currentOp: 1, $all: true })
db.runCommand({currentOp: 1, $all:[{"active" : true}]})
db.runCommand({currentOp: 1, "active" : true})

mongo --port 27017 admin --eval 'db.runCommand({currentOp: 1, $all:[{"active" : true}]})'
mongo --port 27017 admin --eval 'db.runCommand({currentOp: 1,"active" : true})'

cluster

# 副本集群
# 一主一从 一主多从
# 主节点处理客户端请求,记录操作oplog
# 从节点复制主节点数据,获取oplog执行
# 副本集奇数特征

# 副本集群,三个节点中主节点挂掉后,其余两个节点会选举一个主节点,两个节点挂掉集群不可用
# 木桶效应,脑裂问题

# Primary主节点:拥有读写能力,为集群内的副本节点,提供数据拷贝的支持
# Replicate副本节点:拥有读能力,数据完全拷贝自主节点,即主从概念中的从节点
# Arbiter仲裁节点:不具备读写能力,用于故障恢复,提供故障检测、选举投票能力

mkdir data1 data2 data3 logs
./mongod --dbpath ./data1 --logpath logs/mongo1.log --port 27017 --fork --replSet rs0
./mongod --dbpath ./data2 --logpath logs/mongo2.log --port 27018 --fork --replSet rs0
./mongod --dbpath ./data3 --logpath logs/mongo3.log --port 27019 --fork --replSet rs0
mongo
rs.initiate()
rs.conf()
# secondary
rs.add("127.0.0.1:27018")
# arbiter
db.adminCommand({
  "setDefaultRWConcern" : 1,
  "defaultWriteConcern" : {
    "w" : "majority"
  }
});
rs.addArb("127.0.0.1:27019")

rs.status()
# secondary find set
rs.secondaryOk();

mongo --host mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/crm?authSource=crm --quiet
  • 分片集群
# Router路由:负责接收、分发客户端的读写请求,类似于代理中间件;
# Shard分片:存储数据、处理读写请求的具体节点;
# Config配置:存储路由、分片节点的元数据和配置信息;

# Shard Rules:分片规则,也叫分片算法,指分发读写请求的逻辑,如随机、取模等;
# Shard Key:分片键,也叫路由键,指基于文档中的哪个字段进行分片计算;
# Document:文档,这个概念在前面就一直接触过,等价于MySQL中的一条数据;
# Chunk:块,指包含一定范围内多个文档的数据段,属于集群中分割、存储数据的基本单位;
# Shard:分片,每个分片都由一个副本集群组成,一个分片中可以存储多个Chunk数据块;
# Cluster:集群,由多个Shard分片组成,统一对外提供读写服务。

# 高可用
# 两个Mongos路由节点、两个由副本集群组成的分片、一个由副本集群组成的配置节点 2+(2*3)+(1*3)=11
# 实验
# 两个Mongos路由节点、两个单节点分片、一个单配置节点 2+2+1=5
mkdir shard1 shard2 conf1
./mongod --dbpath ./shard1 --logpath logs/mongos1.log --bind_ip 127.0.0.1 --port 27017 --fork --replSet rs-shard1 --shardsvr
mongo
rs.initiate();
rs.status();
exit

./mongod --dbpath ./shard2 --logpath logs/mongos2.log --bind_ip 127.0.0.1 --port 27018 --fork --replSet rs-shard2 --shardsvr
mongo --port 27018
rs.initiate();
rs.status();
exit

./mongod --dbpath ./conf1 --logpath logs/mongoc1.log --bind_ip 127.0.0.1 --port 27019 --fork --replSet rs-conf1 --configsvr
mongo --port 27019
rs.initiate();
rs.status();
exit

./mongos --logpath logs/mongos1.log --port 27020 --fork --bind_ip 127.0.0.1 --configdb rs-conf1/127.0.0.1:27019
./mongos --logpath logs/mongos2.log --port 27021 --fork --bind_ip 127.0.0.1 --configdb rs-conf1/127.0.0.1:27019

mongo --port 27020
use admin
sh.addShard("rs-shard1/127.0.0.1:27017")
sh.addShard("rs-shard2/127.0.0.1:27018")
sh.status()
# sh.addShard("rs-shard1/127.0.0.1:27017","rs-shard1/127.0.0.1:27017","rs-shard1/127.0.0.1:27017")
# db.runCommand({removeShard: "分片的副本集群名称"});
# 分片库配置
use crm
sh.enableSharding("crm");
# db.runCommand({enablesharding: "crm"});
# 分片规则配置, 指定具体的集合、字段
sh.shardCollection("crm.user", {"name": "hashed"});
db.user.insert({name:"py"})
for(i=2;i<=100;i++){db.user.insertOne({_id:i,"name":"go"+i})};
db.info.count()
exit

# 100 100 56 44
mongo --quiet --port 27020 crm --eval 'db.user.count()'
mongo --quiet --port 27021 crm --eval 'db.user.count()'
mongo --quiet --port 27017 crm --eval 'db.user.count()'
mongo --quiet --port 27018 crm --eval 'db.user.count()'

mongo --quiet --port 27020 crm --eval 'db.user.find().forEach(printjson)'

### set collection balance
# db.getSiblingDB("config").collections.find().pretty()
# db.getSiblingDB("config").collections.findOne({_id : "crm.user"}).noBalance
# sh.enableBalancing("crm.user")
# sh.disableBalancing("crm.user")

# sh.getBalancerWindow()
# use config
# db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop : "6:00" } } }, true )

# sh.getBalancerState()
# sh.isBalancerRunning()
# sh.startBalancer()
# sh.stopBalancer()