MongoDB基本操作命令一
安装完成后创建数据目录
MongoDB 将数据目录存储在 db 目录下。但是这个数据目录不会主动创建,我们在安装完成后需要创建它。请注意,数据目录应该放在根目录下 (如: C:\ 或者 D:\ 等 )。
在 D 盘下创建目录:d:\mongoDBdata\db
配置MongoDB服务
创建数据库和日志文件目录:
d:\mongoDBdata\db
d:\mongoDBdata\log\mongod.log
配置文件(一般高版本的会自动创建,没有就自己创建) mongod.cfg
指定 systemLog.path 和 storage.dbPath。具体配置内容如下。
# Where and how to store data. storage: dbPath: D:\mongoDBdata\db journal: enabled: true # engine: # wiredTiger: # where to write logging data. systemLog: destination: file logAppend: true path: D:\mongoDBdata\log\mongod.log # network interfaces net: port: 27017 bindIp: 127.0.0.1
将MongoDB服务器作为Windows服务运行
像上面那样启动mongodb,发现没办法输入命令行了,这是可以采用打开多个窗口来连接,但这样就太麻烦了,解决办法就是将MongoDB服务器作为Windows服务运行。
启动MongoDB服务: net start MongoDB (启动之后在 服务中可看到状态为正在运行)
关闭MongoDB服务: net stop MongoDB
移除MongoDB服务: D:\mongoDB\bin\mongod.exe --remove
由于我们并没有指定mongodb服务的端口号,所以它启动在默认的27017
窗口。
打开浏览器,范围地址http://127.0.0.1:27017/
,可看到如下信息:
It looks like you are trying to access MongoDB over HTTP on the native driver port.
MongoDB 后台管理 Shell
如果你需要进入MongoDB后台管理,你需要先打开mongodb安装目录的下的bin目录,然后执行mongo.exe文件,
MongoDB Shell是 MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。
然后可以执行一些操作:
第一个命令将数字 10 插入到 runoob 集合的 x 字段中:db.runoob.insert({x:10})
查找:db.runoob.find().pretty() //输出格式美化
MongoDB的一些命令:
显示所有数据库列表: show dbs
显示当前数据库对象或集合: db
如果数据库不存在,则创建数据库,否则切换到指定数据库 : use database_name
删除数据库的语法: db.dropDatabase() 删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名
查看已有集合: show tables/collections
创建集合: db.createCollection(name, options)
创建带参数的固定集合:(整个集合空间大小 6142800 B, 文档最大个数为 10000 个)
db.createCollection('collectionName',{capped: true,autoIndexId: true,size:6142800,max: 10000})
集合删除语法格式如下: db.collectionName.drop()
在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合:
db.mycols.insert({'name' : '测试插入时自动创建集合'})
插入文档:
db.collectionName.insert(document)
或
db.collectionName.save(document)
save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 来代替。
insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
db.collectionName.insertOne(): 向指定集合中插入一条文档数据
db.collectionName.insertMany(): 向指定集合中插入多条文档数据
MongoDB 使用 update() 和 save() 方法来更新集合中的文档:
update() 方法: 用于更新已存在的文档
db.collectionName.update(
<query>, //update的查询条件
<update>, //update的对象和一些更新的操作符等
{
upsert: <boolean>, //可选参数,如果不存在 update的记录,是否插入,默认是false,不插入
multi: <boolean>, // 可选参数,默认false,只更新找到的第一条记录,若为 true,把按条件查出来的多条记录全部更新
writeConcern: <document> // 可选,抛出异常的级别
}
)
例子: db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
save()方法: save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入
db.collectionName.save(
<document>, //文档数据
{
witeConcern: <document> // 可选参数,抛出异常的级别
}
)
remove() 删除文档(移除集合中的数据):
db.collectionName.remove(
<query>, // 可选,删除的文档的条件
{
justOne : <boolean>, // 可选,如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false, 则删除所有匹配条件的文档。
writeConcern: <document> // 可选,抛出异常的级别
}
)
注意: 只想删除第一条找到的记录可以设置 justOne 为 1
想删除所有数据, 使用 justOne 默认值 为false
删除集合下的所有数据: db.collectionName.remove({})
remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。
如删除集合下全部文档: db.collectionName.deleteMany({})
删除 status 等于 A 的全部文档: db.collectionName.deleteMany({ status : "A" })
删除 status 等于 D 的一个文档: db.collectionName.deleteOne( { status: "D" } )
查询文档: 主要使用 find()方法,以非结构化的方式来显示所有文档。
db.collectionName.find(query,projection); // query 可选参数,使用查询操作符查询条件 projection 可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。
需要以易读的方式来读取数据,可以使用 pretty() 方法: db.collectionName.find().pretty()
findOne() 方法,只返回一个文档。
条件语句查询:(条件操作符)
db.col.find({"num":50}).pretty() // num = 50
db.col.find({"num":{$lt:50}}).pretty() // num < 50
db.col.find({"num":{$lte:50}}).pretty() // num <= 50
db.col.find({"num":{$gt:50}}).pretty() // num > 50
db.col.find({"num":{$gt:50}}).pretty() // num > 50
db.col.find({"num":{$gte:50}}).pretty() // num >= 50
db.col.find({"num":{$ne:50}}).pretty() // num != 50
db.col.find({"num":{$lt:200,$gt:100}}) // 100 < num < 200
MongoDB and 条件:
db.col.find({key1:value, key2:value2}).pretty()
MongoDB or 条件:
db.col.find(
{
$or : [
{key1 : value1}, {key2 : value2}
]
}
).pretty()
MongoDB and 和 or 联合使用: 类似 SQL where key1 > value1 and (key2 = value2 or key3 = value3)
db.col.find({key1 : {$gt : value1}, $or[{key2 : value2}, {key3 : value3}]).pretty()
MongoDB $type 条件操作符:( $type 操作符是基于 BSON 类型来检索集合中匹配的数据类型,并返回结果。)
例如,想过去 col 集合中 title 为 String 的数据: (2 代表字符串类型 strig) 参考 :MongoDB $type 操作符 | 菜鸟教程
db.col.find({"title" : {$type : 2}}) 或者 db.col.find({"title" : {$type : "string"}})
MongoDB Limit 于 Skip 方法:
Limit() 方法: 如果你需要在 MongoDB 中读取指定数量的数据记录,可以使用 MongoDB 的 Limit 方法,limit() 方法接受一个数字参数,该参数指定从 MongoDB 中读取的记录条数
db.collectionName.find().limit(number)
Skip() 方法: 使用 skip() 方法来跳过指定数量的数据,skip 方法同样接受一个数字参数作为跳过的记录条数
db.collectionName.find().limit(1).skip(1) //限制显示一条,然后跳过第一条,显示第二条
db.collectionName.find().skip(1) //跳过第一条,显示后面的数据
MongoDB 排序:
sort() 方法: 可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
db.collectionName.find().sort({key:1}) 例子: db.collectionName.find({}, {"title": 1,"_id":0}).sort({"likes": -1})
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()。
MongoDB 索引:(每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。所以,如果你很少对集合进行读取操作,建议不使用索引。)
(由于索引是存储在内存(RAM)中,你应该确保该索引的大小不超过内存的限制。如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降)
最大范围:
1.集合中索引不能超过64个。
2.索引名的长度不能超过125个字符
3. 一个复合索引最多可以有31个字段
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
createIndex() 方法来创建索引:
db.collectionName.createIndex(keys, options); // Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可
如: db.col.createIndex({"title" : 1})
createIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
如: db.col.createIndex({"title" : 1, "description": -1})
在后台创建索引 : db.values.createIndex({open : 1, close : 1}, {background : true})
查看集合索引: db.collectionName.getIndexes()
查看集合索引大小:db.collectionName.totalIndexSize()
删除集合所有索引:db.collectionName.dropIndexes()
删除集合指定索引:db.collectionName.dropIndex("索引名称")
注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。
MongoDB 聚合:(MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果)
aggregate() MongoDB中的聚合方法。
db.collectionName.aggregate(AGGREATE_OPERATION)
例子: db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum:1}}}]) //通过字段 by 对数据进行分组,并计算 by 字段相同值的总和
db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) //计算平均值
db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) //获取集合文档对应值得最小值
db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) //获取集合文档对应值得最大值
db.col.aggregate([{$group : {_id : "$by_user", url : {$push : "$url"}}}]) //在结果文档中插入值到一个数组中
db.col.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) //在结果文档中插入值到一个数组中,但不创建副本
db.col.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) //根据资源文档的排序获取第一个文档数据
db.col.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) //根据资源文档的排序获取最后一个文档数据
管道: MongoDB 的聚合管道将 MongoDB 文档在一个管道处理完毕后将结果传递给下一个管道处理
聚合框架中常用的几个操作:
$project: 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match: 用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit: 用来限制MongoDB聚合管道返回的文档数。
$skip: 在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group: 将集合中的文档分组,可用于统计结果。
$sort: 将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
MapReduce 命令:( Map-Reduce 是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE))
MongoDB提供的 Map-Reduce 非常灵活,对于大规模数据分析也相当实用
db.col.mapReduce(
function(){ emit(key, value)} // map 函数 (映射函数 (生成键值对序列,作为 reduce 函数参数)。)
function(key,values){ return reduceFunction } // reduce 函数 (reduce 统计函数,reduce函数的任务就是将 key-values 变成 key-value ,也就是把 values 数组变成一个单一的值 value )
{
out : collection, // out 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)
query : document, // query 一个筛选条件,只有满足条件的文档才会调用 map 函数。(query。limit,sort可以随意组合)
sort : document, // sort 和 limit 结合的 sort 排序参数(也是在发往 map 函数前给文档排序),可以优化分组机制
limit : number // limit 发往 map 函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)
}
)
// 使用 MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调用 emit(key, value), 遍历 collection 中所有的记录, 将 key 与 value 传递给 Reduce 函数进行处理
// Map 函数必须调用 emit(key, value) 返回键值对
MongoDB 复制 (副本集): ( MongoDB 复制是将数据同步在多个服务器的过程,复制还允许您从硬件故障和服务中断中恢复数据)
MongoDB 分片 : 另一种集群,就是分片技术,可以满足 MongoDB 数据量大量增长的需求。
当 MongoDB 存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据
分片实列
分片结构端口分布:
Shard Server 1: 27020
Shard Server 2: 27021
Shard Server 3: 27022
Shard Server 1: 27023
Config Server 4: 27100
Route Process 1: 40000
步骤一:启动 Shard Server
1. 在 D盘文件下创建目录 ( -p 参数表示创建子目录 )
mkdir -p /www/mongoDB/shard/s0
mkdir -p /www/mongoDB/shard/s1
mkdir -p /www/mongoDB/shard/s2
mkdir -p /www/mongoDB/shard/s3
然后命令行执行 :进入到 mongodb 安装目录: cd: D:\mongoDB\bin 执行命令:
mongod --port 27020 --dbpath=D:\mongoDBdata\shard\s0 --logpath=D:\mongoDBdata\shard\log\s0.log --logappend
mongod --port 27021 --dbpath=D:\mongoDBdata\shard\s1 --logpath=D:\mongoDBdata\shard\log\s1.log --logappend
mongod --port 27022 --dbpath=D:\mongoDBdata\shard\s2 --logpath=D:\mongoDBdata\shard\log\s2.log --logappend
mongod --port 27023 --dbpath=D:\mongoDBdata\shard\s3 --logpath=D:\mongoDBdata\shard\log\s3.log --logappend
步骤二:启动 config Server
mkdir -p /www/mongoDB/shard/config
mongod --port 27100 --dbpath=D:\mongoDBdata\shard\config --logpath=D:\mongoDBdata\shard\log\config.log --logappend
步骤三:启动 Route Process
mongos --port 40000 --configdb localhost:27100 --fork --logpath=D:\mongoDBdata\shard\log\route.log --chunkSize 500
( mongos 启动参数中,chunkSize 这一项是用来指定 chunk 的大小的,单位是MB,默认大小为200MB.)
步骤三出现的问题:
原因:
使用的 MongoDB 3.4.10 版,这个版本在之前的版本上有做调整,要求configs服务器是副本集模式。3.2和3.2以下都不做强制要求的。
解决方法:
1.configs服务器配置成副本集模式
2.把MongoDB换成3.4以下版本
步骤四:配置 Sharding
使用 MongoDB Shell 登录到 mongos,添加 Shard 节点。
mongo admin --port 40000
db.runCommand({ addshard:"localhost:27020" })
db.runCommand({ addshard:"localhost:27021" })
db.runCommand({ addshard:"localhost:27022" })
db.runCommand({ addshard:"localhost:270203" })
db.runCommand({ enablesharding:"test" }) //设置分片存储的数据库
db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}})
步骤五:
程序代码内无需太大更改,直接按照连接普通的mongo数据库那样,将数据库连接接入接口40000