MongDB副本集,文档管理
1.副本集介绍:也称为MongoDB复制
指在多个服务器上存储数据副本,并实现数据同步
提高数据可用性、安全性,方便数据故障恢复
副本集工作过程:
至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余是从节点,负责复制主节点数据
常见搭配方式:一主一从、一主多从
主节点记录所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
2.副本集实现方式:
Master-Slave 主从复制:
启动一台服务器时加上“-master”参数,作为主节点
启动其他服务器时加上“-slave”和“-source”参数,作为从节点
主从复制的优点:
从节点可以提供数据查询,降低主节点的访问压力
由从节点执行备份,避免锁定主节点数据
当主节点故障时,可快速切换到从节点,实现高可用
Replica Sets副本集:
从1.6 版本开始支持,优于之前的replication
支持故障自动切换、自动修复成员节点,降低运维成本
Replica Sets副本集的结构类似高可用集群
3.启用副本集模式
启动服务时,指定主机所在副本集名称
l 所有副本集成员使用相同的副本集名称
l --replSet rs1 //指定副本集名称
[root@data51 ~]# vim /usr/local/mongodb/etc/mongodb.conf #51 52 53重复
replSet=rs1 #副本集名称rs1 ,S大写
[root@data51 ~]# mdbstart #启动服务
about to fork child process, waiting until server is ready for connections.
forked process: 1697
child process started successfully, parent exiting
[root@data51 ~]# ss -antulp | grep 27052
tcp LISTEN 0 128 192.168.4.52:27052 *:* users:(("mongod",pid=1697,fd=11))
4.定义副本集列表
[root@server0 ~]# ./mongo --host 192.168.4.61
config = {
_id:"rs1",
members:[
{_id:0,host:"IP地址:端口"},
{_id:1,host:"IP地址:端口"},
{_id:2,host:"IP地址:端口"}
]
}
[root@data51 ~]# vim /usr/local/mongodb/etc/mongodb.conf
> config={
... _id:"rs1",
... members:[
... {_id:0,host:"192.168.4.51:27051"},
... {_id:1,host:"192.168.4.52:27052"},
... {_id:2,host:"192.168.4.53:27053"}
... ]
... }
回车后提示:
{
"_id" : "rs1",
"members" : [
{
"_id" : 0,
"host" : "192.168.4.51:27051"
},
{
"_id" : 0,
"host" : "192.168.4.52:27052"
},
{
"_id" : 0,
"host" : "192.168.4.53:27053"
}
]
}
此时配置完,不能操作数据库,如show dbs会报错,因为默认都是从库,从库上不能任何操作。
定义成员列表不成功,再重新添加报错,怎么办?如下
需要把配置文件中的副本集配置注释掉,再重启,命令行连接进入库,删除local库(db.dropDatabase()),再停服务,重新配置副本集。
> rs.help() #查询命令帮助
rs.status() { replSetGetStatus : 1 } checks repl set status
rs.initiate() { replSetInitiate : null } initiates set with default settings
rs.initiate(cfg) { replSetInitiate : cfg } initiates set with configuration cfg
rs.conf() get the current configuration object from local.system.replset
rs.reconfig(cfg) updates the configuration of a running replica set with cfg (disconnects)
rs.add(hostportstr) add a new member to the set with default attributes (disconnects)
rs.add(membercfgobj) add a new member to the set with extra attributes (disconnects)
rs.addArb(hostportstr) add a new member which is arbiterOnly:true (disconnects)
rs.stepDown([stepdownSecs, catchUpSecs]) step down as primary (disconnects)
rs.syncFrom(hostportstr) make a secondary sync from the given member
rs.freeze(secs) make a node ineligible to become primary for the time specified
rs.remove(hostportstr) remove a host from the replica set (disconnects) #移除副本集
rs.slaveOk() allow queries on secondary nodes
rs.printReplicationInfo() check oplog size and time range
rs.printSlaveReplicationInfo() check replica set members and replication lag
db.isMaster() check who is primary
reconfiguration helpers disconnect from the database so the shell will display
an error, even if the command succeeds.
> rs.conf() # 获取副本集的配置信息
2018-12-26T09:49:48.241+0800 E QUERY [thread1] Error: Could not retrieve replica set config: {
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94,
"codeName" : "NotYetInitialized",
"$clusterTime" : {
"clusterTime" : Timestamp(0, 0),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
} :
rs.conf@src/mongo/shell/utils.js:1323:11
@(shell):1:1
5.创建副本集
初始化Replica Sets环境:执行如下命令 > rs.initiate(config)
> rs.initiate(config) #初始化
{
"ok" : 1,
"operationTime" : Timestamp(1545789984, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1545789984, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
rs1:SECONDARY>
rs1:PRIMARY> show dbs #查看数据库
admin 0.000GB
config 0.000GB
local 0.000GB
6.查看副本集信息
rs1:PRIMARY> rs.status #查看状态信息
rs1:PRIMARY> rs.isMaster() #查看是否为master库(51上查看)
{
"hosts" : [
"192.168.4.51:27051",
"192.168.4.52:27052",
"192.168.4.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.4.51:27051",
"me" : "192.168.4.51:27051",
"electionId" : ObjectId("7fffffff0000000000000001"),
"lastWrite" : {
52和53上查看:是从库 不能执行管理命令
rs1:SECONDARY> rs.isMaster()
{
"hosts" : [
"192.168.4.51:27051",
"192.168.4.52:27052",
"192.168.4.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : false,
"secondary" : true,
"primary" : "192.168.4.51:27051",
"me" : "192.168.4.52:27052",
7.验证副本集信息
rs1:PRIMARY> db.getMongo().setSlaveOk() #同步数据验证,允许从库查看数据(必须从库上执行)
8.客户端登陆主库 写数据验证
[root@data50 ~]# /usr/local/mongodb/bin/mongo -host 192.168.4.51 -port 27051
rs1:PRIMARY> use test
switched to db test
rs1:PRIMARY> db.t1.insert({name:"qiaoxin"})
WriteResult({ "nInserted" : 1 })
rs1:PRIMARY> db.t1.find()
{ "_id" : ObjectId("5c22ebb2c722b2c42356302a"), "name" : "qiaoxin" }
从库52和53上查看:
rs1:SECONDARY> use test
switched to db test
rs1:SECONDARY> show tables
t1
rs1:SECONDARY> db.t1.find()
{ "_id" : ObjectId("5c22ebb2c722b2c42356302a"), "name" : "qiaoxin" }
9.测试高可用
[root@data51 ~]# mdbstop #把主库51停掉
killing process with pid: 1753
[root@data51 ~]# ss -antulp | grep mond
52上查看:
rs1:PRIMARY> rs.isMaster() #52上查看已经变成主了
{
"hosts" : [
"192.168.4.51:27051",
"192.168.4.52:27052",
"192.168.4.53:27053"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.4.52:27052",
"me" : "192.168.4.52:27052",
主库宕掉后,最先喊当主库的从库 且30秒内其他主库没有喊,就升级为主库,如果同时喊 两者pk,谁的数据新谁当老大。可以在设置副本集的时候指定priority优先级。
> config={
... _id:"rs1",
... members:[
... {_id:0,host:"192.168.4.51:27051",priority:10},
... {_id:1,host:"192.168.4.52:27052",priority:11},
... {_id:2,host:"192.168.4.53:27053",priority:12}
51重新起服:查看状态会自动成功从库。
10.恢复独立数据库
rs1:PRIMARY> use local #进入local库
switched to db local
rs1:PRIMARY> show tables #查看表
me
oplog.rs
replset.election
replset.minvalid
replset.oplogTruncateAfterPoint
startup_log
system.replset
system.rollback.id
rs1:PRIMARY> db.me.find() #此表存放本主机信息
{ "_id" : ObjectId("5c22d7a24aeb2f5a31b38dfc"), "host" : "data52" }
rs1:PRIMARY> db.oplog.rs.find() #此表存放操作日志
rs1:PRIMARY> db.system.replset.find() #此表存放成员信息
rs1:PRIMARY> db.dropDatabase() #删除副本集信息 因为此时没停止副本集的服务
{
"ok" : 0,
"errmsg" : "Cannot drop 'local' database while replication is active",
[root@data52 ~]# /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/etc/mongodb.conf --shutdown #停mongodb服务
[root@data52 ~]# vim /usr/local/mongodb/etc/mongodb.conf #配置文件注释掉副本集
#replSet=rs1
[root@data52 ~]# /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/etc/mongodb.conf #重启mongodb服务
rs1:PRIMARY> db.dropDatabase() #此时再删就可以了
1.插入新文档
save()
格式
> db.集合名.save({ key:“值”,key:”值”})
注意
集合不存在时创建集合,然后再插入记录
_id字段值已存在时,修改文档字段值
_id字段值不存在时,插入文档
insert()
格式
> db.集合名.insert({key:"值",key:"值"})
注意
集合不存在时创建集合,然后再插入记录
_id字段值已存在时,放弃插入
_id字段值不存在时,插入文档
insertMany()
> db.t1.save({_id:1,name:"qiaoxin"})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 1 })
> db.t1.save({name:"linlin"})
WriteResult({ "nInserted" : 1 })
> db.t1.find()
{ "_id" : ObjectId("5c231b148bedc088ce691f0e"), "id" : 1, "age" : 9 }
{ "_id" : 1, "name" : "qiaoxin" }
{ "_id" : ObjectId("5c231d618bedc088ce691f0f"), "name" : "linlin" }
> db.t1.save({-id:1,name:"le"})
2018-12-26T14:21:26.639+0800 E QUERY [thread1] SyntaxError: invalid property id @(shell):1:12
> db.t1.save({_id:1,name:"le"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.t1.find()
{ "_id" : ObjectId("5c231b148bedc088ce691f0e"), "id" : 1, "age" : 9 }
{ "_id" : 1, "name" : "le" }
{ "_id" : ObjectId("5c231d618bedc088ce691f0f"), "name" : "linlin" }
> db.t1.insert({_id:1,name:"le"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: db2.t1 index: _id_ dup key: { : 1.0 }"
}
})
> db.t1.insert({_id:2,name:"le"})
WriteResult({ "nInserted" : 1 })
> db.t1.find()
{ "_id" : ObjectId("5c231b148bedc088ce691f0e"), "id" : 1, "age" : 9 }
{ "_id" : 1, "name" : "le" }
{ "_id" : ObjectId("5c231d618bedc088ce691f0f"), "name" : "linlin" }
{ "_id" : 2, "name" : "le" }
> db.t1.insertMany([{_id:3,name:"le"},{_id:4,name:"qi"}])
{ "acknowledged" : true, "insertedIds" : [ 3, 4 ] }
> db.t1.find()
{ "_id" : ObjectId("5c231b148bedc088ce691f0e"), "id" : 1, "age" : 9 }
{ "_id" : 1, "name" : "le" }
{ "_id" : ObjectId("5c231d618bedc088ce691f0f"), "name" : "linlin" }
{ "_id" : 2, "name" : "le" }
{ "_id" : 3, "name" : "le" }
{ "_id" : 4, "name" : "qi" }
2.查询文档
显示所有行(默认输出20行,输入it可显示后续行)
> db.集合名.find()
> db.passwd.find()
```````````````````````````
Type "it" for more
显示第1行
> db.集合名.findOne()
> db.passwd.findOne()
{
"_id" : ObjectId("5c21f74fc8c60845e2dca240"),
"name" : "root",
"passwd" : "x",
"uid" : 0,
"gid" : 0,
"comment" : "root",
"homedir" : "/root",
"shell" : "/bin/bash"
}
指定查询条件并指定显示的字段
> db.集合名.find({条件},{定义显示的字段})
> db.user.find({},{_id:0,name:1,shell:1}).pretty() #pretty() 竖着显示
//0 不显示,1 显示
> db.passwd.find({shell:"/bin/bash"},{_id:0,name:1,shell:1}).pretty() #查询shell是/bin/bash的行 加1显示,加0不显示,默认不显示,_id必须指定0,否则会显示id :如果指定了一个1显示,其他都默认0不显示
{ "name" : "root", "shell" : "/bin/bash" }
{ "name" : "lisi", "shell" : "/bin/bash" }
> db.passwd.find({shell:"/bin/bash"},{name:1,shell:1}).pretty() #id不加0 默认显示 但其他字段不加0 默认就是0 不显示
{
"_id" : ObjectId("5c21f74fc8c60845e2dca240"),
"name" : "root",
"shell" : "/bin/bash"
}
{
"_id" : ObjectId("5c21f74fc8c60845e2dca267"),
"name" : "lisi",
"shell" : "/bin/bash"
}
> db.passwd.find({shell:"/bin/bash"},{_id:0}) #如果指指定id是0 那么其他都默认为1(显示)
{ "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "homedir" : "/root", "shell" : "/bin/bash" }
{ "name" : "lisi", "passwd" : "x", "uid" : 1000, "gid" : 1000, "comment" : "lisi", "homedir" : "/home/lisi", "shell" : "/bin/bash" }
行数显示限制
limit(数字) //显示前几行 备注:与sort或skip联合用的时候,limit最后执行
> db.集合名.find().limit(3)
> db.passwd.find().limit(3)
{ "_id" : ObjectId("5c21f74fc8c60845e2dca240"), "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "homedir" : "/root", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca241"), "name" : "bin", "passwd" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homedir" : "/bin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca242"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin" }
> db.passwd.find().count()
41
> db.passwd.count()
41
skip(数字) //跳过前几行
> db.集合名.find().skip(2)
> db.passwd.find().limit(3).skip(2) #跳过前2行 再显示前3行
{ "_id" : ObjectId("5c21f74fc8c60845e2dca242"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca243"), "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "homedir" : "/var/adm", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca244"), "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "homedir" : "/var/spool/lpd", "shell" : "/sbin/nologin" }
> db.passwd.find().limit(3)
{ "_id" : ObjectId("5c21f74fc8c60845e2dca240"), "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "homedir" : "/root", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca241"), "name" : "bin", "passwd" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homedir" : "/bin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca242"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin" }
> db.passwd.find().limit(3).skip(4)
{ "_id" : ObjectId("5c21f74fc8c60845e2dca244"), "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "homedir" : "/var/spool/lpd", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca245"), "name" : "sync", "passwd" : "x", "uid" : 5, "gid" : 0, "comment" : "sync", "homedir" : "/sbin", "shell" : "/bin/sync" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca246"), "name" : "shutdown", "passwd" : "x", "uid" : 6, "gid" : 0, "comment" : "shutdown", "homedir" : "/sbin", "shell" : "/sbin/shutdown" }
> db.passwd.find().skip(4).limit(3)
{ "_id" : ObjectId("5c21f74fc8c60845e2dca244"), "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "homedir" : "/var/spool/lpd", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca245"), "name" : "sync", "passwd" : "x", "uid" : 5, "gid" : 0, "comment" : "sync", "homedir" : "/sbin", "shell" : "/bin/sync" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca246"), "name" : "shutdown", "passwd" : "x", "uid" : 6, "gid" : 0, "comment" : "shutdown", "homedir" : "/sbin", "shell" : "/sbin/shutdown" }
sort(字段名) //1升序,-1降序
> db.集合名.find().sort({age:1|-1})
> db.passwd.find().limit(3).sort({uid:-1}) #先整体排序 再取前三行
{ "_id" : ObjectId("5c21f74fc8c60845e2dca25d"), "name" : "nfsnobody", "passwd" : "x", "uid" : 65534, "gid" : 65534, "comment" : "Anonymous NFS User", "homedir" : "/var/lib/nfs", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca267"), "name" : "lisi", "passwd" : "x", "uid" : 1000, "gid" : 1000, "comment" : "lisi", "homedir" : "/home/lisi", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca24f"), "name" : "polkitd", "passwd" : "x", "uid" : 999, "gid" : 998, "comment" : "User for polkitd", "homedir" : "/", "shell" : "/sbin/nologin" }
> db.passwd.find().limit(3).sort({uid:1})
{ "_id" : ObjectId("5c21f74fc8c60845e2dca240"), "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "homedir" : "/root", "shell" : "/bin/bash" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca241"), "name" : "bin", "passwd" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homedir" : "/bin", "shell" : "/sbin/nologin" }
{ "_id" : ObjectId("5c21f74fc8c60845e2dca242"), "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin" }
3.修改文档
类 型 用 途
$set 修改文档指定字段的值
$unset 删除记录中的字段
$push 向数组内添加新元素
$pull 删除数组中的指定元素
$pop 删除数组头尾部元素
$addToSet 避免数组重复赋值
$inc 字段自加或自减
1)update()
语法格式
> db.集合名.update({条件},{修改的字段})
2)多文档更新
语法格式:默认只更新与条件匹配的第1行
> db.user.update({条件},{$set:{修改的字段}}) //默认只更新与条件匹配的第1行
>db.user.update({条件},{$set:{修改的字段}} ,false,true)
> db.user.update({name:"bin"},{$set:{password:"abc12123"}},false,true)
3)$set/$unset
$set 条件匹配时,修改指定字段的值
> db.user.update({条件},$set: {修改的字段})
> db.user3.update({name:"bin"},{$set:{password:"A"}})
$unset 删除与条件匹配文档的字段
> db.集合名.update({条件},{$unset:{key:values}})
> db.user3.update({name:"bin"},{$unset:{password:"A"}})
4)$inc
$inc 条件匹配时,字段值自加或自减
> db.集合名.update({条件},{$inc:{字段名:数字}})
> db.user.update({name:"bin"},{$inc:{uid:2}}) //字段值自加2
> db.user.update({name:“bin”},{$inc:{uid:-1}}) //字段值自减1
5)$push/$addToSet
$push 向数组中添加新元素
> db.集合名.update({条件},{$push:{数组名:"值"}})
> db.user.insert({name:"bob",likes:["a","b","c","d","e","f"]})
> db.user.update({name:“bob”},{$push:{likes:“w"}})
$addToSet 避免重复添加
> db.集合名.update({条件},{$addToSet:{数组名:"值"}})
> db.user.update({name:"bob"},{$addToSet:{likes:"f"}})
6)$pop/$pull
$pop 从数组头部删除一个元素
> db.集合名.update({条件},{$pop:{数组名:数字}})
> db.user.update({name:"bob"},{$pop:{likes:1}})
> db.user.update({name:"bob"},{$pop:{likes:-1}})
$pull 删除数组指定元素
> db.集合名.update({条件},{$pull:{数组名:值}})
> db.user.update({name:"bob"},{$pull:{likes:"b"}})
> db.passwd.find({uid:{$lte:4}},{_id:0})
{ "name" : "root", "passwd" : "x", "uid" : 0, "gid" : 0, "comment" : "root", "homedir" : "/root", "shell" : "/bin/bash" }
{ "name" : "bin", "passwd" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homedir" : "/bin", "shell" : "/sbin/nologin" }
{ "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin" }
{ "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "homedir" : "/var/adm", "shell" : "/sbin/nologin" }
{ "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "homedir" : "/var/spool/lpd", "shell" : "/sbin/nologin" }
> db.passwd.update({uid:{$lte:4}},{password:"qqqqqqqqqqqq"}) #默认只改第一行
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.passwd.find({uid:{$lte:4}},{_id:0}) #少了一行 因为上一条uptade命令把其他字段都删除了
{ "name" : "bin", "passwd" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homedir" : "/bin", "shell" : "/sbin/nologin" }
{ "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin" }
{ "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "homedir" : "/var/adm", "shell" : "/sbin/nologin" }
{ "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "homedir" : "/var/spool/lpd", "shell" : "/sbin/nologin" }
> db.passwd.find({password:"qqqqqqqqqqqq"}) #此行除了password字段,其他被删除
{ "_id" : ObjectId("5c21f74fc8c60845e2dca240"), "password" : "qqqqqqqqqqqq" }
> db.passwd.update({uid:{$lte:4}},{$set:{password:"qqqqqqqqqqqq"}},false,true)
#set只改password false,true表示全部符合的行都改(须与set合用)
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })
有几行匹配 有几个字段被修改
> db.passwd.find({uid:{$lte:4}},{_id:0})
{ "name" : "bin", "passwd" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homedir" : "/bin", "shell" : "/sbin/nologin", "password" : "qqqqqqqqqqqq" }
{ "name" : "daemon", "passwd" : "x", "uid" : 2, "gid" : 2, "comment" : "daemon", "homedir" : "/sbin", "shell" : "/sbin/nologin", "password" : "qqqqqqqqqqqq" }
{ "name" : "adm", "passwd" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "homedir" : "/var/adm", "shell" : "/sbin/nologin", "password" : "qqqqqqqqqqqq" }
{ "name" : "lp", "passwd" : "x", "uid" : 4, "gid" : 7, "comment" : "lp", "homedir" : "/var/spool/lpd", "shell" : "/sbin/nologin", "password" : "qqqqqqqqqqqq" }
>
4.删除文档
$drop/$remove
1)$drop 删除集合的同时删除索引
> db.集合名.drop( )
> db.user.drop( )
2)$remove() 删除文档时不删除索引
> db.集合名.remove({}) //删除所有文档
> db.集合名.remove({条件}) //删除与条件匹配的文档
> db.user.remove({uid:{$lte:10}})
> db.user.remove({})
5.匹配条件(查询 修改 删除)
1)简单条件:
> db.集合名.find({key:"值"})
> db.集合名.find({key:"值",keyname:"值"})
> db.user.find({shell:"/bin/bash"})
> db.user.find({shell:"/bin/bash",name:"root"}) # shell为/bin/bash 而且name为root 的行
2)范围比较:
$in 在…里
$nin 不在…里
$or 或
> db.user.find({uid:{$in:[1,6,9]}}) #如果范围是字符,需要用双引号
> db.user.find({uid:{$nin:[1,6,9]}})
> db.user.find({$or: [{name:"root"},{uid:1} ]})
> db.passwd.find({shell:{$nin:["/bin/bash","/sbin/nologin"]}},{_id:0,name:1,shell:1})
{ "name" : "sync", "shell" : "/bin/sync" }
{ "name" : "shutdown", "shell" : "/sbin/shutdown" }
{ "name" : "halt", "shell" : "/sbin/halt" }
{ "name" : "mysql", "shell" : "/bin/false" }
> db.passwd.find({$or:[{shell:"/bin/bash"},{name:"root"}]},{_id:0,name:1,shell:1})
{ "name" : "root", "shell" : "/bin/bash" }
{ "name" : "lisi", "shell" : "/bin/bash" }
3)正则匹配
> db.user.find({name: /^a/ })
> db.passwd.find({name:/t$/},{_id:0,name:1})
{ "name" : "root" }
{ "name" : "halt" }
{ "name" : "libstoragemgmt" }
{ "name" : "abrt" }
{ "name" : "rtkit" }
{ "name" : "setroubleshoot" }
4)数值比较
$lt $lte $gt $gte $ne
< <= > >= !=
> db.user.find( { uid: { $gte:10,$lte:40} } , {_id:0,name:1,uid:1})
> db.user.find({uid:{$lte:5}})
> db.passwd.find({uid:{$lte:10}},{_id:0,name:1,shell:1})
{ "name" : "root", "shell" : "/bin/bash" }
{ "name" : "bin", "shell" : "/sbin/nologin" }
{ "name" : "daemon", "shell" : "/sbin/nologin" }
{ "name" : "adm", "shell" : "/sbin/nologin" }
{ "name" : "lp", "shell" : "/sbin/nologin" }
{ "name" : "sync", "shell" : "/bin/sync" }
{ "name" : "shutdown", "shell" : "/sbin/shutdown" }
{ "name" : "halt", "shell" : "/sbin/halt" }
{ "name" : "mail", "shell" : "/sbin/nologin" }
> db.passwd.find({uid:{$gte:10,$lte:20}},{_id:0,name:1,shell:1})
{ "name" : "operator", "shell" : "/sbin/nologin" }
{ "name" : "games", "shell" : "/sbin/nologin" }
{ "name" : "ftp", "shell" : "/sbin/nologin" }
> db.passwd.find({$or:[{uid:0},{uid:1}]},{_id:0,name:1,uid:1})
{ "name" : "root", "uid" : 0 }
{ "name" : "bin", "uid" : 1 }
> db.passwd.find({$or:[{uid:{$gte:10}},{uid:{$lte:5}}]},{_id:0,name:1,uid:1})
{ "name" : "root", "uid" : 0 }
{ "name" : "bin", "uid" : 1 }
{ "name" : "daemon", "uid" : 2 }
{ "name" : "adm", "uid" : 3 }
{ "name" : "lp", "uid" : 4 }
{ "name" : "sync", "uid" : 5 }
{ "name" : "operator", "uid" : 11 }
{ "name" : "games", "uid" : 12 }
{ "name" : "ftp", "uid" : 14 }
{ "name" : "nobody", "uid" : 99 }
{ "name" : "systemd-network", "uid" : 192 }
{ "name" : "dbus", "uid" : 81 }
{ "name" : "polkitd", "uid" : 999 }
{ "name" : "libstoragemgmt", "uid" : 998 }
{ "name" : "rpc", "uid" : 32 }
{ "name" : "colord", "uid" : 997 }
{ "name" : "saslauth", "uid" : 996 }
{ "name" : "abrt", "uid" : 173 }
{ "name" : "rtkit", "uid" : 172 }
{ "name" : "radvd", "uid" : 75 }
Type "it" for more
5)匹配null ,也可以匹配没有的字段
> db.user.save({name:null,uid:null})
> db.user.find({name:null})
> db.user.find({"_id": ObjectId("5afd0ddbd42772e7e458fc75"),"name" : null, "uid" : null })
1 案例1:配置MongoDB副本集
1.1 问题
- 具体要求:
- 准备3台mongodb服务器
- 配置副本集服务
- 验证副本集配置
1.2 方案
准备三台虚拟机,配置mongodb副本集,ip分别为192.158.4.51, 192.168.4.52,192.168.4.53其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据,实现存储数据副本,提高了数据的可用性,具体分配如表-1所示:
表-1

1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建mongodb副本集
1)三台主机安装mongodb(以4.51为例)
- [root@mongodb51 ~]# cd mongodb/
- [root@mongodb51 mongodb]# mkdir /usr/local/mongodb
- [root@mongodb51 mongodb]# cd /usr/local/mongodb
- [root@mongodb51 mongodb]# cp -r \
- /root/mongodb/mongodb-linux-x86_64-rhel70-3.6.3/bin/ .
- [root@mongodb51 mongodb]# ls
- bin
- [root@mongodb51 mongodb]# mkdir etc
- [root@mongodb51 mongodb]# mkdir log
- [root@mongodb51 mongodb]# mkdir -p data/db
- [root@mongodb51 mongodb]# vim etc/mongodb.conf
- dbpath=/usr/local/mongodb/data/db/
- logpath=/usr/local/mongodb/log/mongodb.log
- logappend=true
- fork=true
- bind_ip=192.168.4.51
- port=27077
- replSet=rs1
- //加入到副本集,rs1名字随便起,想知道谁和我在一个副本集里,三台机器的名字一样,都写rs1
2)设置PATH变量
- [root@mongodb51 mongodb]# vim /etc/profile
- export PATH=/usr/local/mongodb/bin:$PATH
- [root@mongodb51 mongodb]# source /etc/profile
3)由于启动和停止服务名字太长,可以起一个别名
给停止服务起一个别名
- [root@mongodb51 mongodb]# alias cmdb='mongod --dbpath=/usr/local/mongodb/data/db/ --shutdown'
给启动服务起一个别名
- [root@mongodb51 mongodb]# alias smdb='mongod -f /usr/local/mongodb/etc/mongodb.conf'
4)启动服务并连接
- [root@mongodb51 ~]# smdb
- about to fork child process, waiting until server is ready for connections.
- forked process: 5656
- child process started successfully, parent exiting
- [root@mongodb51 ~]# mongo --host 192.168.4.51 --port 27077
- MongoDB shell version v3.6.3
- connecting to: mongodb://192.168.4.51:27077/
- MongoDB server version: 3.6.3
- ...
- >
5)配置集群信息,任意一台都可以,在这里在51上面操作
- > rs1_config = { //rs1_config随便起变量名,要记住
- _id:"rs1", //必须为rs1这个,三台主机集群名,配置文件里面写的是这个
- members:[
- {_id:0,host:"192.168.4.51:27077"}, //_id值随意,host值固定
- {_id:1,host:"192.168.4.52:27078"},
- {_id:2,host:"192.168.4.53:27079"}
- ]
- }; //回车,出现下面情况为成功
- {
- "_id" : "rs1",
- "members" : [
- {
- "_id" : 0,
- "host" : "192.168.4.51:27077"
- },
- {
- "_id" : 1,
- "host" : "192.168.4.52:27078"
- },
- {
- "_id" : 2,
- "host" : "192.168.4.53:27079"
- }
- ]
- }
- >
6)初始化Replica Sets环境
- > rs.initiate(rs1_config)
- {
- "ok" : 1,
- "operationTime" : Timestamp(1538187475, 1),
- "$clusterTime" : {
- "clusterTime" : Timestamp(1538187475, 1),
- "signature" : {
- "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
- "keyId" : NumberLong(0)
- }
- }
- }
- rs1:SECONDARY>
- rs1:PRIMARY> //提示PRIMARY,51为主
7)在52和53上面查看
- [root@mongodb52 ~]# mongo --host 192.168.4.52 --port 27078
- MongoDB shell version v3.6.3
- connecting to: mongodb://192.168.4.52:27078/
- MongoDB server version: 3.6.3
- ...
- ...
- rs1:SECONDARY> //提示SECONDARY,52为从
- rs1:SECONDARY>
- rs1:SECONDARY>
- [root@192 ~]# mongo --host 192.168.4.53 --port 27079
- MongoDB shell version v3.6.3
- connecting to: mongodb://192.168.4.53:27079/
- MongoDB server version: 3.6.3
- ...
- ...
- rs1:SECONDARY> //提示SECONDARY,53为从
- rs1:SECONDARY>
注意:如果初始化错误,重启服务登陆之后重新设置变量,之后再重新初始化
8)查看状态信息
- rs1:PRIMARY> rs.status()
- ...
- "members" : [
- {
- "_id" : 0,
- "name" : "192.168.4.51:27077",
- "health" : 1,
- "state" : 1,
- "stateStr" : "PRIMARY",
- "uptime" : 2295,
- ...
- ...
- },
- {
- "_id" : 1,
- "name" : "192.168.4.52:27078",
- "health" : 1,
- "state" : 2,
- "stateStr" : "SECONDARY",
- "uptime" : 384,
- ...
- ...
- },
- {
- "_id" : 2,
- "name" : "192.168.4.53:27079",
- "health" : 1,
- "state" : 2,
- "stateStr" : "SECONDARY",
- ...
- ...
9)查看是否是master库
- rs1:PRIMARY> rs .isMaster( )
- {
- "hosts" : [
- "192.168.4.51:27077",
- "192.168.4.52:27078",
- "192.168.4.53:27079"
- ],
- "setName" : "rs1",
- "setVersion" : 1,
- "ismaster" : true, //主库
- "secondary" : false,
- "primary" : "192.168.4.51:27077",
- "me" : "192.168.4.51:27077",
- ...
- ...
10)验证副本集,同步数据验证(51上面写数据)
- rs1:PRIMARY> use gamedb2
- switched to db gamedb2
- rs1:PRIMARY> db.a.save({name:"yaya",age:75,em:"p@.com"})
- WriteResult({ "nInserted" : 1 })
52上面查看
- [root@mongodb52 ~]# mongo --host 192.168.4.52 --port 27078
- rs1:SECONDARY> db.getMongo().setSlaveOk()
- rs1:SECONDARY> show dbs //有gamedb2库
- admin 0.000GB
- config 0.000GB
- ddsdb 0.000GB
- gamedb2 0.000GB
- local 0.000GB
- test 0.000GB
步骤三:切换主库验证
1)自动切换主库验证
关闭51
- [root@mongodb51 ~]# cmdb //之前设置的别名
- killing process with pid: 5656
查看52和53
- [root@mongodb52 ~]# mongo --host 192.168.4.52 --port 27078
- MongoDB shell version v3.6.3
- connecting to: mongodb://192.168.4.52:27078/
- MongoDB server version: 3.6.3
- ...
- ...
- rs1:PRIMARY> //52为主
- rs1:PRIMARY>
- [root@mongodb53 ~]# mongo --host 192.168.4.53 --port 27079
- MongoDB shell version v3.6.3
- connecting to: mongodb://192.168.4.53:27079/
- MongoDB server version: 3.6.3
- ...
- ...
- rs1:SECONDARY> //53为从
启动51,启动后不会再变为主,会成为52的从
- [root@mongodb51 ~]# smdb
- about to fork child process, waiting until server is ready for connections.
- forked process: 6598
- child process started successfully, parent exiting
- rs1:SECONDARY> rs.isMaster()
- {
- "hosts" : [
- "192.168.4.51:27077",
- "192.168.4.52:27078",
- "192.168.4.53:27079"
- ],
- "setName" : "rs1",
- "setVersion" : 1,
- "ismaster" : false,
- "secondary" : true,
- "primary" : "192.168.4.52:27078",
- "me" : "192.168.4.51:27077",
- ...
2 案例2:文档管理
2.1 问题
- 基于MongoDB环境完成下列练习:
- 插入文档
- 查询文档
- 更新文档
- 删除文档
2.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:管理文档
1)把系统用户信息/etc/passwd存储到mdb库下的user集合里
- rs1:PRIMARY> use mdb
- switched to db mdb
- rs1:PRIMARY> db.user.save({name:"yaya",password:"x",uid:9999,gid:9999,comment:"",homdir:"/home",shell:"/bin/bash"})
- WriteResult({ "nInserted" : 1 })
- rs1:PRIMARY> exit
- bye
- [root@mongodb52 ~]# mongoexport --host 192.168.4.52 --port 27078 -d mdb -c user -f name,password,uid,gid,comment,homdir,shell --type=csv -o /tmp/user.csv
- 2018-09-29T11:04:14.967+0800 connected to: 192.168.4.52:27078
- 2018-09-29T11:04:14.968+0800 exported 1 record
- [root@mongodb52 ~]# cp /etc/passwd /tmp
- [root@mongodb52 ~]# sed -i 's/:/,/g' /tmp/passwd
- [root@mongodb52 ~]# sed -i '$r /tmp/passwd' /tmp/user.csv
- [root@mongodb52 ~]# mongoimport --host 192.168.4.52 --port 27078 -d mdb -c user --headerline --type=csv /tmp/user.csv
- 2018-09-29T11:06:08.355+0800 connected to: 192.168.4.52:27078
- 2018-09-29T11:06:08.363+0800 imported 41 documents
2)查看
- [root@mongodb52 ~]# mongo --host 192.168.4.52 --port 27078
- rs1:PRIMARY> use mdb
- switched to db mdb
- rs1:PRIMARY> db.user.findOne()
- {
- "_id" : ObjectId("5baeeb37ce3cc5539aa21f38"),
- "name" : "yaya",
- "password" : "x",
- "uid" : 9999,
- "gid" : 9999,
- "comment" : "",
- "homdir" : "/home",
- "shell" : "/bin/bash"
- }
db.user.find({条件},{定义显示的字段}) #指定查询条件并指定显示的字段
- rs1:PRIMARY> db.user.find()
- { "_id" : ObjectId("5baeeb37ce3cc5539aa21f38"), "name" : "yaya", "password" : "x", "uid" : 9999, "gid" : 9999, "comment" : "", "homdir" : "/home", "shell" : "/bin/bash" }
- ...
- Type "it" for more //出现这个按it,默认出现20行
查看每行的name字段
- rs1:PRIMARY> db.user.find({},{name:1})
- { "_id" : ObjectId("5baeeb37ce3cc5539aa21f38"), "name" : "yaya" }
- ...
- ...
- { "_id" : ObjectId("5baeec2001805180a1011843"), "name" : "rpc" }
- Type "it" for more
不看_id字段
- rs1:PRIMARY> db.user.find({},{_id:0})
- { "name" : "yaya", "password" : "x", "uid" : 9999, "gid" : 9999, "comment" : "", "homdir" : "/home", "shell" : "/bin/bash" }
- ...
- ...
- { "name" : "rpc", "password" : "x", "uid" : 32, "gid" : 32, "comment" : "Rpcbind Daemon", "homdir" : "/var/lib/rpcbind", "shell" : "/sbin/nologin" }
- Type "it" for more
不看_id那一列,看name那一列
- rs1:PRIMARY> db.user.find({},{_id:0,name:1})
- { "name" : "yaya" }
- ...
- ...
- { "name" : "rpc" }
- Type "it" for more
查看以a开头的name字段
- rs1:PRIMARY> db.user.find({name:/^a/},{_id:0})
- { "name" : "adm", "password" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "homdir" : "/var/adm", "shell" : "/sbin/nologin" }
- { "name" : "abrt", "password" : "x", "uid" : 173, "gid" : 173, "comment" : "", "homdir" : "/etc/abrt", "shell" : "/sbin/nologin" }
- { "name" : "avahi", "password" : "x", "uid" : 70, "gid" : 70, "comment" : "Avahi mDNS/DNS-SD Stack", "homdir" : "/var/run/avahi-daemon", "shell" : "/sbin/nologin" }
显示查询结果的前一行
limit 数字
- rs1:PRIMARY> db.user.find({name:/^a/},{_id:0}).limit (1)
- { "name" : "adm", "password" : "x", "uid" : 3, "gid" : 4, "comment" : "adm", "homdir" : "/var/adm", "shell" : "/sbin/nologin" }
显示name字段以a开头的第一行
- rs1:PRIMARY> db.user.findOne({name:/^a/},{_id:0,name:1,shell:1,uid:1})
- { "name" : "adm", "uid" : 3, "shell" : "/sbin/nologin" }
跳过几行显示 (2行)
skip 数字
- rs1:PRIMARY> db.user.find({name:/^a/},{_id:0,name:1,shell:1}).skip (2)
- { "name" : "avahi", "shell" : "/sbin/nologin" }
默认升序排序
sort 字段名
- rs1:PRIMARY> db.user.find({name:/^a/},{_id:0,name:1,shell:1,uid:1}).sort({uid:1})
- { "name" : "adm", "uid" : 3, "shell" : "/sbin/nologin" }
- { "name" : "avahi", "uid" : 70, "shell" : "/sbin/nologin" }
- { "name" : "abrt", "uid" : 173, "shell" : "/sbin/nologin" }
降序排序
- rs1:PRIMARY> db.user.find({name:/^a/},{_id:0,name:1,shell:1,uid:1}).sort({uid:-1})
- { "name" : "abrt", "uid" : 173, "shell" : "/sbin/nologin" }
- { "name" : "avahi", "uid" : 70, "shell" : "/sbin/nologin" }
- { "name" : "adm", "uid" : 3, "shell" : "/sbin/nologin" }
显示name字段以a开头和uid为3的所有行
- rs1:PRIMARY> db.user.find({name:/^a/,uid:3},{_id:0,name:1,shell:1,uid:1})
- { "name" : "adm", "uid" : 3, "shell" : "/sbin/nologin" }
3)条件判断的表示方式
$in 在...里
- rs1:PRIMARY> db.user.find({uid:{$in:[1,6,9]}}) //uid的为1或者6或者9的匹配
- { "_id" : ObjectId("5baeec2001805180a1011833"), "name" : "bin", "password" : "x", "uid" : 1, "gid" : 1, "comment" : "bin", "homdir" : "/bin", "shell" : "/sbin/nologin" }
- { "_id" : ObjectId("5baeec2001805180a1011838"), "name" : "shutdown", "password" : "x", "uid" : 6, "gid" : 0, "comment" : "shutdown", "homdir" : "/sbin", "shell" : "/sbin/shutdown" }
$nin 不在...里
- rs1:PRIMARY> db.user.find({uid:{$nin:[1,6,9]}},{_id:0,name:1,uid:1})
- { "name" : "yaya", "uid" : 9999 }
- ...
- ...
- { "name" : "saslauth", "uid" : 996 }
- Type "it" for more
$or 条件满足任意其中一个即可
- rs1:PRIMARY> db.user.find({$or:[{name:"root"},{uid:1}]},{_id:0,name:1,uid:1})
- { "name" : "root", "uid" : 0 }
- { "name" : "bin", "uid" : 1 }
4)正则匹配,以a开头的name字段
- rs1:PRIMARY> db.user.find({name:/^a/},{_id:0,name:1,uid:1})
- { "name" : "adm", "uid" : 3 }
- { "name" : "abrt", "uid" : 173 }
- { "name" : "avahi", "uid" : 70 }
5)数值比较
$lt(小于) $lte(小于等于) $gt(大于) $gte(大于等于) $ne(不等于)
- rs1:PRIMARY> db.user.find({uid:{$gte:10,$lte:40}},{_id:0,name:1,uid:1})
- { "name" : "operator", "uid" : 11 }
- { "name" : "games", "uid" : 12 }
- { "name" : "ftp", "uid" : 14 }
- { "name" : "rpc", "uid" : 32 }
- { "name" : "rpcuser", "uid" : 29 }
- { "name" : "ntp", "uid" : 38 }
匹配null:可以匹配没有的字段,也可以检查这个字段有没有
- rs1:PRIMARY> db.user.save({name:null,uid:null})
- WriteResult({ "nInserted" : 1 })
- rs1:PRIMARY> db.user.find({name:null})
- { "_id" : ObjectId("5baef385f9f3bf625ea1dbd6"), "name" : null, "uid" : null }
- rs1:PRIMARY> db.user.find({shell:null}) //表示此条文档没有shell字段
- { "_id" : ObjectId("5baef385f9f3bf625ea1dbd6"), "name" : null, "uid" : null }
- rs1:PRIMARY>
6)save和insert的区别
相同点:当集合不存在时创建集合,并插入记录
不同点:save() _id字段值已经存在时,修改文档字段值
insert() _id字段值已经存在时,放弃修改文档字段值
- rs1:PRIMARY> db.t1.save({name:"bob",age:19})
- WriteResult({ "nInserted" : 1 })
- rs1:PRIMARY> db.t1.insert({name:"bob",age:19})
- WriteResult({ "nInserted" : 1 })
- rs1:PRIMARY> db.t1.save({_id:7,name:"bob",age:19})
- WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 7 })
- rs1:PRIMARY> db.t1.find()
- ...
- ...
- { "_id" : 7, "name" : "bob", "age" : 19 }
- rs1:PRIMARY> db.t1.save({_id:7,name:"tom",age:19}) //把上一条的记录直接修改
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.t1.find()
- ...
- ...
- { "_id" : 7, "name" : "tom", "age" : 19 }
- rs1:PRIMARY>
- rs1:PRIMARY>
- rs1:PRIMARY> db.t1.insert({_id:8,name:"tom",age:19}) //可以存上
- WriteResult({ "nInserted" : 1 })
- rs1:PRIMARY> db.t1.insert({_id:8,name:"tom",age:19}) //存不上
- WriteResult({
- "nInserted" : 0,
- "writeError" : {
- "code" : 11000,
- "errmsg" : "E11000 duplicate key error collection: mdb.t1 index: _id_ dup key: { : 8.0 }"
- }
- })
7)插入多行文档
- rs1:PRIMARY> db.t1.insertMany([{name:"xiaojiu"},{name:"laoshi"}])
- {
- "acknowledged" : true,
- "insertedIds" : [
- ObjectId("5baef526f9f3bf625ea1dbd9"),
- ObjectId("5baef526f9f3bf625ea1dbda")
- ]
- }
- rs1:PRIMARY> db.t1.find()
- ...
- ...
- { "_id" : ObjectId("5baef526f9f3bf625ea1dbd9"), "name" : "xiaojiu" }
- { "_id" : ObjectId("5baef526f9f3bf625ea1dbda"), "name" : "laoshi" }
8)update修改
- rs1:PRIMARY> db.user.update({name:"root"},{password:"XXX"})
- //如果这一列不写完整,这一行除了password这一行,这一列的其他值都没有了相当于删除(要写完整)
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.t1.find({name:"root"})
- rs1:PRIMARY> db.user.find({name:"root"}) //没有东西,除了password:"XXX"
9)$set 条件匹配时,修改指定字段的值(局部修改)
- rs1:PRIMARY> db.user.update({name:"adm"},{$set:{password:"AAA"}})
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.find({name:"adm"}) //还存在
- { "_id" : ObjectId("5baeec2001805180a1011835"), "name" : "adm", "password" : "AAA", "uid" : 3, "gid" : 4, "comment" : "adm", "homdir" : "/var/adm", "shell" : "/sbin/nologin" }
- rs1:PRIMARY> db.user.update({name:/^r/},{$set:{password:"FFF"}})
- //默认修改匹配条件的第一行
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.update({name:/^a/},{$set:{password:"FFF"}},false,true)
- //改匹配到的所有
- WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
10)$unset 删除与条件匹配文档的字段
- rs1:PRIMARY> db.user.update({name:"sync"},{$unset:{password:1}})
- //删除password字段
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
11)数组
- rs1:PRIMARY> db.user.insert({name:"bob",like:["a","b","c","d","e","f",]})
- WriteResult({ "nInserted" : 1 })
$pop 删除数组末尾一个元素,1删除最后一个,-1删除第一个
- rs1:PRIMARY> db.user.update({name:"bob"},{$pop:{like:1}})
- //删除匹配的第一条的最后一个
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.update({name:"bob"},{$pop:{like:-1}})
- //删除匹配的第一条的第一个
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
$push 向数组中添加新元素
- rs1:PRIMARY> db.user.update({name:"bob"},{$push:{like:"Z"}}) //默认添加到最后
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.update({name:"bob"},{$push:{like:"W"}})
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.find({name:"bob"})
- { "_id" : ObjectId("5baef7b2034891a205de2959"), "name" : "bob", "like" : [ "b", "c", "d", "e", "Z", "W" ] }
$addToSet 避免重复添加
- rs1:PRIMARY> db.user.update({name:"bob"},{$addToSet:{like:"W"}})
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
- rs1:PRIMARY> db.user.find({name:"bob"})
- { "_id" : ObjectId("5baef7b2034891a205de2959"), "name" : "bob", "like" : [ "b", "c", "d", "e", "Z", "W" ] }
$pull 删除数组里的指定元素,若有两个bob可以用_id值定义把name:"bob"换成id值
- rs1:PRIMARY> db.user.update({name:"bob"},{$pull:{like:"c"}})
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.find({name:"bob"})
- { "_id" : ObjectId("5baef7b2034891a205de2959"), "name" : "bob", "like" : [ "b", "d", "e", "Z", "W" ] }
- rs1:PRIMARY> db.user.update({"_id":ObjectId("5afc1a717eff45e9cfc57ed3")},{$push:{like:"S"}})
- WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
- rs1:PRIMARY>
$inc 条件匹配时,字段值自加或自减
- rs1:PRIMARY> db.user.update({uid:{$lte:10}},{$inc:{uid:2}})
- //设置字段值自加2,默认改第一行
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- rs1:PRIMARY> db.user.update({uid:{$lte:10}},{$inc:{uid:2}},false,true)
- //设置字段值自加2,false,true改全部
- WriteResult({ "nMatched" : 8, "nUpserted" : 0, "nModified" : 8 })
- rs1:PRIMARY>
- rs1:PRIMARY> db.user.update({uid:{$lte:10}},{$inc:{uid:-1}})
- //负数时是自减1,默认改第一行
- WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
12)删除文档
remove()与drop()的区别
remove()删除文档时不删除索引
drop()删除集合的时候同时删除索引
- rs1:PRIMARY> db.t1.remove({})
- WriteResult({ "nRemoved" : 6 })
- rs1:PRIMARY> db.user.remove({name:"/^a/"}) //删除以a开头的记录
- WriteResult({ "nRemoved" : 0 })
- rs1:PRIMARY> db.t1.drop() //删除集合t1
- true
- rs1:PRIMARY>
浙公网安备 33010602011771号