mongodb基本命令,mongodb集群原理分析
集合:
1、集合没有固定数据格式。
2、
数据:
时间类型:
Date() 当前时间(js时间)
new Date() 格林尼治时间(object)
ISODate() 格林尼治时间(object)
转换:
new Date()/ISODate().toLocaleString() 转为本地时间Date()
new Date()/ISODate().valueOf() 转为时间戳
ID:
mongodb每个文档必须有一个_id键
默认_id = ObjectId()(对象)
命令:
数据库:
use db_n 使用库
db db_n 显示库名
show dbs 查看所有库
use database_name 删除库
->db.dropDatabase()
集合:
show collections 查看全部集合
db.createCollection("name", {options}) 创建集合
options:
capped 布尔 true固定集合,须指定size,默认false
size int 固定长度,超过后自动覆盖最早的文档,优先级大于max
autoIndexId 布尔 true自动在_id创建索引,默认true
max int 固定集合包含文档最大数量
db.c_n/db.getCollection("c_n") 使用集合
db.c_n.drop() 删除集合
固定集合:
db.createCollection("log",{capped: true, size: 10000, max: 5000}) 创建限制集合
db.isCapped() 是否为限制集合
db.runConmand({"convertToCapped": "mycoll", size: 100000}) 将集合转化为限制集
操作符:
$ 代表自己
文档:
pretty() 格式化读取
-------------------------------------------------------------------------------------------------------------------------
查询文档:
db.c_n.find({},{指定字段}) 查询文档 ({}中两个同名键,前面查询会被覆盖)
-----
db.c_n.find({},{aa:1,_id:0}) 指定aa字段,排除_id(_id默认会显示)
-----
aa:{$type:1} aa为数字类型
-----
aa: 1 aa = 1
aa:{$lt:50} aa<50
aa:{$lte:50} aa<=50
bb:{$gt:50} bb>50
bb:{$gte:50} bb>=50
bb:{$ne:50} bb!=50
aa:{$gte:10,$lte:20} 10<=aa<=20
aa:{$eq:20} aa=20
aa:{$in: [0,1,2,3] } aa in[]
aa:{$nin: [0,1,2,3] } aa not in[]
-----
$or:[{aa:1},{aa:2}] or
$and:[{},{}] and
$not:{$gt:2} not in (aa>2)
$nor:[] not or
$where:function(){
if(this.age>18){
return true;
}
return false;
}
/
$where:"this.age > 18" 自定义函数逻辑筛选
分页:
db.c_n.find().limit(2) 只查前2条
db.c_n.find().skip(2) 跳过前2条
排序:
db.c_n.find().sort({aa:1,bb:-1}) 排序,aa升序,bb降序
嵌套:
db.c_n.find({"aa.x":2}) 查询x符合的数据
一个:
db.c_n.findOne({}) 查询一个
正则:
aa:/你/ 包含 你
aa:/^你/ 以 你 开头
aa:/你$/ 以 你 结尾
游标:
var aa = db.c_n.find()
aa.hasNext()
aa.next()
-------------------------------------------------------------------------------------------------------------------------
插入文档:
db.c_n.insert(
[ {},{},{} ]/{} ,
{
writeConcern: <document> ,
ordered: <boolean>(是否按顺序插入,默认true顺序添加,出错后面无法添加/false不严格顺序,中间一条错误后面也能添加)
}
) 插入文档
db.c_n.insertOne({}) 插入一个文档
{ "acknowledged" : true, "insertedIds" : [ ObjectId("562a94d381cb9f1cd6eb0e1a"), ] } 返回值
db.c_n.insertMany(
[ {},{},{} ] ,
{
writeConcern: <document> ,
ordered: <boolean>(是否按顺序插入,默认true顺序添加,出错后面无法添加/false不严格顺序,中间一条错误后面也能添加)
}
) 批量(数组形式)添加
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5ccaa77a8467059db6186d23"),
ObjectId("5ccaa77a8467059db6186d24"),
ObjectId("5ccaa77a8467059db6186d25")
]
} 批量(数组形式)返回值
-------------------------------------------------------------------------------------------------------------------------
批量操作:
如果一个执行list 包含添加、更新 、删除操作 ,mongodb 会把操作分成三个组:第一个 执行insert 操作 第二个执行更新操作 第三个执行删除操作。
var bulk = db.test.initializeOrderedBulkOp();
bluk.insert();
bluk.update();
bluk.find({}).remove();
bluk.getOperations();(查看分组情况)
bluk.execute();(提交) 批量操作(指令)
返回: "batchType" : 1, //1 insert 2 update 3 remove
-------------------------------------------------------------------------------------------------------------------------
db.c_n.save({}) 插入(无_id)/修改(全部替换)
-------------------------------------------------------------------------------------------------------------------------
修改文档:
db.c_n.update(
{
<query>
},
{
<update>
},
{
upsert: <boolean>(不存在记录是否插入 false(默认)不插入/true插入),
multi: <boolean>(false(默认)更新第一条数据/true更新所有匹配数据),
writeConcern: <document>
}
) 修改文档字段
修改符号:
$inc:{aa: 1} 将aa加1
$set:{aa: 2} 把aa字段改为2
$unset:{cc: 1} 将cc字段删除
$push:{aa: 2} (数组)将2添加到aa数组,若不存在数组则自动创建
$pushAll:{aa:[c]} (数组)将c数组添加到aa数组后
$addToSet:{aa:2} (数组)将2添加到数组,2在数组不存在时才添加
$pop:{aa:-1/1} (数组)删除数组最前面、最后面的一个值
$pull:{aa:2} (数组)删除数组中为2的值
$pullAll:{aa:[1,2]} (数组)删除数组批量值
$rename:{old:new} 重命名键
-------------------------------------------------------------------------------------------------------------------------
删除文档:
db.c_n.remove(
{<query>},
{
justOne:<boolean>(是否删除首个 false(默认)否/true是),
writeConcern:<document>
}
) 删除文档
db.c_n.remove({}) 删除所有文档
-------------------------------------------------------------------------------------------------------------------------
类型筛选:
aa:{$type}
typeof 指定类型
-------------------------------------------------------------------------------------------------------------------------
索引:
db.c_n.createIndex(keys,options) 创建单个索引
db.c_n.createIndex({k1,k2,k3},{op}) 创建复合索引1
// db.c_n.ensureIndex({k1,k2,k3},{op}) 创建复合索引2(mongodb3.0开始废弃)
db.c_n.dropIndexes()/dropIndex("_name") 删除索引
db.c_n.getIndexes()/getIndex("_name") 查看索引
db.c_n.totalIndexSize() 索引大小
稀疏索引:
db.c_n.creatIndex({aaa:1},{name:"index1", sparse: true})
非阻塞建立索引:
db.c_n.creatIndex({},{background: true})
唯一索引:
db.c_n.creatIndex({},{unique: true})
TTL(只对时间类型有效):
db.createIndex({},{expireAfterSeconds: 60})
地理空间索引:
db.createIndex({"_name":"2d"})
数据结构:_name:{k1:120,k2:38} 或 _name:[120,38]
地理最近:
find({_name:{$near:[x,y]}}) (默认返回100个)
db.runCommand({geoNear:"c_n",near:[130,38],num:2}) (返回dis距离,stats状态)
*形状范围:
$within
内嵌文档:
db.c_n.createIndex("aaa.xxx",options)
索引排序:
若未对目标字段建立索引,mongodb将会把所有数据提取到内存进行排序,无索引排序使用个数限制的。
注意:
1、联合索引最左缀匹配原则,多条件查询有效。
2、单列多个索引只用到最左边那个。
-------------------------------------------------------------------------------------------------------------------------
统计函数:
db.runCommand({'distinct':'c_n','key':'fied','query':{}})
db.c_n.find({query}).limit(n).count(true/非0) 条件筛选后的数量
db.c_n.count({query}) 数量
db.c_n.distinct(“fied”,{query}) 去重
db.c_n.group({key,reduce,initial[,keyf][,cond][,finalize]}) 分组(最多返回20000个)
分组统计:https://blog.csdn.net/iteye_19607/article/details/82644559
db.c_n.group({
"key":{"k1":true}
"initial":{}
"$reduce":function(){
}
"condition":{query}
})
注意:
db.collection.group()使用JavaScript,它受到了一些性能上的限制。大多数情况下,$ group在Aggregation Pipeline提供了一种具有较少的限制适用的替代。可以通过指定的键的集合中的文档和执行简单的聚合函数
-------------------------------------------------------------------------------------------------------------------------
聚合查询:https://www.cnblogs.com/zhoujie/p/mongo1.html (结果限制大小16m)
db.c_n.aggregate([{ag1},{ag2}]) 聚合查询
$match:{query} 匹配条件
$sort:{aa:1/-1} 排序
$limit:10 输出条数
$skip:20 跳过条数
$unwind:"$aa" 将数组拆分
$out:"c_n" 将结果集迁移到c_n
$group *分组
$group:{_id:"$name",bbb:{$sum:1}}
_id:"$name" 指定分组字段,并以_id键返回数据
$sum 记录每组数据个数
-------------------------------------------------------------------------------------------------------------------------
结果重塑:
-------------------------------------------------------------------------------------------------------------------------
统计例子:
-------------------------------------------------------------------------------------------------------------------------
查询分析:
1、开启profile功能(慢查询记录):
db.getProfilingLevel() 返回level 值0关闭/1慢日志/2
db.setProfilingLevel(level,50(ms)) 记录大于50ms的日志
db.system.profile.find() 查询慢日志
-------------------------------------------------------------------------------------------------------------------------
mongo数据导入导出:
备份/恢复:mongodump/mongorestore
内存日志:journal:db文件下的journal目录
journalCommitInterval = 200 启动项配置journal刷新时间
导入/导出集合:mongoimport/mongoexport
-------------------------------------------------------------------------------------------------------------------------
mongodb集群:
0、副本集原理:
a.一个为主节点,其余的都为从节点。
b.主节点上能够完成读写操作,从节点仅能用于读操作。
c.同步:
(1)第一次启动,删除除了local以外的库,数据全量同步。
(2)同步后,各个从节点通过主节点oplog来复制数据并应用于本地。
(3)宕机或者oplog操作大于一轮未同步,数据全量同步。
(4)从节点通过检查本地oplog最新点和主节点最久点作比较,同步操作。
(5)oplogSize设置较大值避免全量同步。
d.主节点需要记录所有曾删改操作,这些记录保存在local库的oplog文件。
e.oplog:包括:ts时间、op操作类型、ns集合、o文档
(1)oplog为固定集合,超过oplogSize旧值会被覆盖。
(2)oplog 具有幂等性,即无论执行几次其结果一致(例如多次增加)。
(3)oplog包含一个递增的序号来记录操作的时效性。
f.集群中的各节点还会通过传递心跳(默认2s)信息来检测各自的健康状况。
g.主节点选举:
(1)投票,优先级最高的(优先级相同时数据最新的)为主节点。
(2)主节点通过心跳判断集群中多少节点对其可见,小于一半时降级。
(4)选举成功后集群以主节点oplog为最新数据,其他节点的操作都会回
滚,所有节点连接新的活跃节点后要重新同步。这些节点会查看自己的
oplog,找出其中活跃节点没有执行过的操作,然后向活跃节点请求这些操
作影响的文档的最新副本。正在执行重新同步的节点被视为恢复中,在完
成这个过程前,不能成为活跃节点候选者。
(3)参与选举节点数必须大于副本总节点数的一半,如果小于一半则所有
节点变成只读状态。
h.推荐MongoDB副本节点最少为3台,建议副本集成员为奇数,最多12个副
本节点,最多7个节点参与选举,过多时会增加复制压力。
i.所有的Secondary都宕机了,只剩下Primary。最后Primary会变Secondary,
不能提供服务。
1、副本集群管理:
rs.:副本命令,是replSet是缩写,代表副本集。
config={"_id":"shard1", "members":[
{"_id":1,"host":"120.77.37.94:27017","priority":1}
,{"_id": 2,"host":"47.107.174.213:27017","priority":2}
,{"_id": 3,"host":"132.232.156.103:27017","arbiterOnly":true(只作为仲裁节点)}] }
rs.initiate(config)
rs.status() //查看成员的运行状态等信息
rs.config() //查看配置信息
*rs.slaveOk() //允许在SECONDARY节点上进行查询操作,默认从节点不具有查询
功能
rs.isMaster() //查询该节点是否是主节点
rs.add({"ip:port"}) //添加新的节点到该副本集中
rs.remove({"ip:port"}) //从副本集中删除节点
2、主从复制:
--only 从节点指定复制某个数据库,默认是复制全部数据库
--slavedelay 从节点设置主数据库同步数据的延迟(单位是秒)
--fastsync 从节点以主数据库的节点快照为节点启动从数据库
--autoresync 从节点如果不同步则从新同步数据库(即选择当通过热添加了一台从服务器之后,从服务器选择是否更新主服务器之间的数据)
--oplogSize 主节点设置oplog的大小(主节点操作记录存储到local的oplog中)
主节点:
master=true #开启主节点
从节点:
slave=true #开启从节点
source 120.77.37.94:27017 #指定主节点
*shell添加主节点:
use local
db.sourse.insert({"host","120.222.222.22"})
*shell删除主节点:
db.sourse.remove({"host","120.222.222.22"})
3、切片集群:http://www.lanceyan.com/tech/arch/mongodb_shard1.html
注:切片权限和副本集权限是分开管理的。
-------------------------------------------------------------------------------------------------------------------------
mongodb引擎:mongod --storageEngine mmapv1
1、wiredTiger引擎:3.0新增,3.2之后默认引擎。官方宣称在read、insert和复杂的
update下具有更高的性能。
(1)所有的write请求都基于“文档级别”的lock。
(2)通过在配置文件中指定“cacheSizeGB”参数设定引擎使用的内存量,此内存用于
缓存工作集数据(索引、namespace,未提交的write,query缓冲等)。
(3)wiredTiger每隔60秒(默认)或者待写入的数据达到2G时,将内存中的数据变更
flush到磁盘中的数据文件中,并做一个标记点。
(4)对于write操作,首先被持久写入journal,然后在内存中保存变更数据。journal日
志默认每个100毫秒同步磁盘一次,每100M数据生成一个新的journal文件,journal
默认使用了snappy压缩,检测点创建后,此前的journal日志即可清除。
2、MMAPv1引擎:
(1)所有的write请求都基于“collection”的lock。
(2)将数据文件映射到内存中。
-------------------------------------------------------------------------------------------------------------------------
mongodb版本:
3.2联合查询 look up / mongoose