------------ MongoDB 的注意点:
-
启动MongoDB数据库服务:
sudo service mongod start
-
重启MongoDB
sudo service mongod restart
-
启动MongoDB数据库shell 客户端:
mongo
-
卸载MongoDB:
1.停止MongoDB
sudo service mongod stop
2.删除以前安装的所有MongoDB软件包
sudo apt-get purge mongodb-org *
3.删除数据目录
sudo rm -r / var / log / mongodb
sudo rm -r / var / lib / mongodb -
MongoDB数据库的命令:如果是单个单词组成,则默认小写;如果有多个单词组成,则第一个单词首字母小写,后面的单词首字母大写。 如:db.dropDatabase()
-
MongoDB数据库的命令参数:基本都是以字典键值对形式传递。
-
一个MongoDB里可以有多个 数据库(db),一个数据库里可以有多个 集合(collection),一个集合里可以有多个 文档(data),每个文档数据都是由 字典键值对 形式保存。
-
MongoDB里的数据库不需要单独创建,通过 use 切换即可使用。如果数据库里没有数据,数据库不会创建;当数据库里有数据时,数据库才会被创建。
-
数据库不需要单独创建,但是 集合 和 文档 需要单独创建。
--------- MongoDB 数据库的基本使用:
1.查看当前所在的数据库
> db
2.查看MongoDB里所有的数据库
> show dbs
3.切换到指定的数据库
> use XXX
4.查看当前数据库下的所有 集合(表)
> show collections
5.查看指定集合 xxx 的所有数据
> db.xxx.find()
6.删除当前所在数据库
> db.dropDatabase()
--------- MongoDB 集合的基本使用:
1.在当前数据库下创建集合
> db.createCollection("xxx")
2.查看当前数据库下所有集合
> show collections
3.删除当前数据库下的指定集合 xxx
> db.xxx.drop()
--------- MongoDB 文档的增删改查:
------增加数据:
insert()
1.
> db.stu.insert({_id : 1, name : "guojing", age : 30})
2.创建data数据再增加数据
> data = {}
> data._id = 2
> data.name = "huangrong"
> data.age = 20
> db.stu.insert(data)
-------- 删除数据:
remove() : 第一个参数是条件,第二个参数 justOne 默认是false,表示删除全部
1.根据条件 删除所有符合条件的数据
> db.stu.remove({ age : 30})
2.根据条件,删除第一个符合条件的数据
> db.stu.remove({ age : 30}, {justOne : true})
3.不限定条件,全部删除
> db.stu.remove({})
4.删除集合,对应数据也被删除
> db.stu.drop()
5.删除数据库
> db.dropDatabase()
--------- 修改数据
update() 根据条件修改文档数据,可以添加三个参数:
第一个参数表示 查询条件
第二个参数表示 修改后的数据
第三个参数表示 是否全部修改(默认只修改第一个数据)
1.根据条件,修改文档数据
将age 为30的第一条文档数据,替换为 第二个参数的文档,注意_id不会修改
> db.stu.update({age : 30}, {name : "郭靖", age : 100, gender : true})
2.根据条件,修改/添加 文档中的特定字段的值 $set
> db.stu.update({_id : 2}, {$set : {gender : true, name : "郭靖"} })
3.不指定条件,修改/添加 文档中特定字段的值
> db.stu.update({}, {$set : {name : "黄蓉"}})
“注意:上面三种写法,都只能修改第一个匹配结果。”
4.修改所有符合条件的文档数据
{multi : true}: 默认是false,只修改第一个匹配的文档;
设为true,表示将匹配到的所有文档进行修改,
将所有文档数据 的age 修改为 20
> db.stu.update({}, {$set : {age : 20}}, {multi : true})
– save : insert + update
语法等同于insert,根据_id进行操作,区别:
- 如果数据存在,insert会报错,save就会修改数据
- 如果数据不存在,二者都是添加数据
如果_id : 1 存在:
> db.stu.insert({_id : 1, name : "黄蓉"}) # 报错
> db.stu.save({_id : 1, name : "黄蓉"}) # 修改
------------------ 查询
db.stu.drop()
db.stu.insert({_id : 1, name:'郭靖',hometown:'蒙古',age:20,gender:true})
db.stu.insert({_id : 2, name:'黄蓉',hometown:'桃花岛',age:18,gender:false})
db.stu.insert({_id : 3, name:'华筝',hometown:'蒙古',age:18,gender:false})
db.stu.insert({_id : 4, name:'黄药师',hometown:'桃花岛',age:40,gender:true})
db.stu.insert({_id : 5, name:'段誉',hometown:'大理',age:16,gender:true})
db.stu.insert({_id : 6, name:'段王爷',hometown:'大理',age:45,gender:true})
1.基本查询:
- find() : 查找所有符合条件的文档
查找所有年龄为18的文档
> db.stu.find({age : 18})
- findOne() : 查找第一个符合条件的文档
查找第一个年龄为18的文档
> db.stu.findOne({age : 18})
- pretty(): 格式化输出查询结果
例:
> db.stu.find({age : 18}).pertty()
2.比较运算符
默认是等于
$lt : 小于
$gt : 大于
$lte : 小于等于
$gte : 大于等于
$ne : 不等于
查找所有年龄大于等于18的文档
> db.stu.find({age : {$gte : 18}})
3.逻辑运算符
查询条件可以写多个,默认是 and
- 默认是 and :
所有条件都满足
> db.stu.find({age : 18, gender : false})
查找所有年龄小于等于20,男性
> db.stu.find({age : {$lte : 20}, gender : true})
> db.stu.find({
$and : [
{age : {$lte : 20}},
{gender : true}
]
})
- $or : 满足任意一个条件即可
查找所有年龄大于等于20,或者性别为男性的文档
> db.stu.find({$or : [{age : {$gte : 20}}, {gender : true}]})
- $and 和 $or 的混合使用:
年龄大于18,或者男性,并且籍贯是 桃花岛。
> db.stu.find({$and : [{$or : [{age : {$gt : 18}}, {gender : true}]}, {hometown : "桃花岛"}]})
> db.stu.find({$or : [{age : {$gt : 18}}, {gender : true}], hometown : "桃花岛"})
4.范围运算符
- $in ; 属于这个范围内满足条件
查找所有年龄为 18、20、25 的文档
> db.stu.find({age : {$in : [18, 20, 25]}})
查找所有籍贯为"蒙古", "大理"的
> db.stu.find({hometown : {$in : ["蒙古", "大理"]}})
- $nin : 不属于这个范围内满足条件
查找所有年龄不为 18、20、25 的文档
> db.stu.find({age : {$nin : [18, 20, 25]}})
查找所有籍贯不为"蒙古", "大理"的
> db.stu.find({hometown : {$nin : ["蒙古", "大理"]}})
5.正则表达式
- 将正则表达式写在 / / 之间,,注意不能用字符串表示
模糊查询
> db.stu.find({name : /药/}) # 只要名字带药即可
> db.stu.find({name : /^药/}) # 名字必须第一个就是药
- 通过$regex 修饰符 指明使用 正则表达式,
可以写正则表达式字符串
> db.stu.find({name : {$regex : "药"}}) # 只要名字带药即可
> db.stu.find({name : {$regex : "^药"}}) # 名字必须第一个就是药
Python正则表达式操作MongoDB进行查询
> nsq_reg = re.compile(r'\[(\d*).(\d*).(\d*).(\d*):(.*)\]')
> messageArr = Message.find({'$and': [{'mac_ip': mac_ip}, {'content': {'$not': nsq_reg}}]})
上面两种写法的结果相同,但是更推荐第二种的写法,不会引起歧义。
- 使用正则查询字母,
通过 $options 设置忽略字母大小写
> db.stu.insert({ "_id" : 7, "name" : "BigCat", "hometown" : "合肥", "age" : 18, "gender" : true })
查找名字有big的文档,同时忽略字母大小写
> db.stu.find({name : {$regex : "big", $options : "$i"}})
6.自定义函数查询
查找所有籍贯为 蒙古的 文档
> db.stu.find({$where : function() {return this.hometown == "蒙古"}})
-------------- 查询结果是显示
-------- limit() 和 skip()
1.limit() 表示显示前3个文档
> db.stu.find().limit(3)
2.skip() 表示跳过前3个文档开始显示
> db.stu.find().skip(3)
3.limit() + skip() 表示显示指定部分的文档
只显示第四条到第五条数据
> db.stu.find().skip(3).limit(2)
----------- 投影
表示只显示查询结果的指定字段
指定字段为 1 或 true 表示显示,默认_id是显示的
指定_id 为 0 或 false 表示不显示 _id
查询所有年龄大于20文档,只显示name,_id 不显示
> db.stu.find({age : {$gt : 20}}, {name : 1, _id : 0})
--------------排序 sort()
指定字段为 1 表示升序排序(从小到大),-1 为降序排序(从大到小)
将查询结果按age进行降序排序
> db.stu.find().sort({age : -1})
组合排序:先按第一个age排序,如果age值相同,再按第二个_id进行排序
> db.stu.find().sort({age : -1, _id : 1})
-------------- 统计个数 count()
1.根据查询结构进行统计
> db.stu.find({age : {$lte : 18}, gender : false}).count()
2.直接根据条件进行统计
> db.stu.count({age : {$lte : 18}, gender : false})
------------- 去重显示 distinct()
接收两个参数:第一个参数是最后要显示的字段,第二个参数是查询条件
显示所有年龄大于20的名字,并去重返回列表
> db.stu.distinct("name", {age : {$gte : 20}})
> db.stu.distinct("hometown", {age : {$gte : 16}, gender : true})
> db.stu.distinct("hometown", {$or : [{age : {$gte : 30}}, {gender : true}]})
----------------- MongoDB 的聚合运算
$group : 将集合的所有文档按 _id 指定的分组依据进行分组,再调用聚合方法进行统计
$sum : 1 : 统计个数
将所有文档按 gender 进行分组,再统计每个分组的个数,并将结果保存到 count
> db.stu.aggregate( [ {$group : {_id : "$gender", count : {$sum : 1}}} ] )
{ "_id" : false, "count" : 2 }
{ "_id" : true, "count" : 5 }
将所有文档按 hometown 进行分组,再统计每个分组的个数
> db.stu.aggregate( [ {$group : {_id : "$hometown", count : {$sum : 1}}} ] )
{ "_id" : "合肥", "count" : 1 }
{ "_id" : "大理", "count" : 2 }
{ "_id" : "桃花岛", "count" : 2 }
{ "_id" : "蒙古", "count" : 2 }
$sum :字段名 : 统计指定字段的值的总和
将所有文档按 gender 进行分组,再统计每个分组的 age 总和,并保存到 age_sum 里
> db.stu.aggregate( [ {$group : {_id : "$gender", age_sum : {$sum : "$age"}}} ] )
{ "_id" : false, "agesum" : 36 }
{ "_id" : true, "agesum" : 139 }
将所有文档按 hometown 进行分组,再统计每个分组的 age 总和,并保存到 age_sum 里
> db.stu.aggregate( [ {$group : {_id : "$hometown", age_sum : {$sum : "$age"}}} ] )
{ "_id" : "合肥", "agesum" : 18 }
{ "_id" : "大理", "agesum" : 61 }
{ "_id" : "桃花岛", "agesum" : 58 }
{ "_id" : "蒙古", "agesum" : 38 }
将所有文档分为一组,并统计所有 age值的总和
> db.stu.aggregate( [ {$group : {_id : null, agesum : {$sum : "$age"}}} ] )
{ "_id" : null, "agesum" : 175 }
将所有文档按 hometown 进行分组,再统计每个分组的 age 的平均值
> db.stu.aggregate( [{ $group : {_id : "$hometown", avg_age : {$avg : "$age"} } }] )
{ "_id" : "合肥", "avg_age" : 18 }
{ "_id" : "大理", "avg_age" : 30.5 }
{ "_id" : "桃花岛", "avg_age" : 29 }
{ "_id" : "蒙古", "avg_age" : 19 }
将所有文档按 hometown 进行分组,并统计 age 的最大值
> db.stu.aggregate( [ {$group : {_id : "$hometown", max_age : {$max : "$age"}}} ] )
{ "_id" : "合肥", "max_age" : 18 }
{ "_id" : "大理", "max_age" : 45 }
{ "_id" : "桃花岛", "max_age" : 40 }
{ "_id" : "蒙古", "max_age" : 20 }
统计 age 的最小值
> db.stu.aggregate( [ {$group : {_id : "$hometown", min_age : {$min : "$age"}}} ] )
将所有文档按 hometown 进行分组,再统计不同分组的 第一个name
> db.stu.aggregate( [ {$group : {_id : "$hometown", first_name : {$first : "$name"}}} ] )
{ "_id" : "合肥", "first_name" : "BigCat" }
{ "_id" : "大理", "first_name" : "段誉" }
{ "_id" : "桃花岛", "first_name" : "黄蓉" }
{ "_id" : "蒙古", "first_name" : "郭靖" }
将所有文档按 hometown 进行分组,再统计不同分组的 最后一个 name
> db.stu.aggregate( [ {$group : {_id : "$hometown", last_name : {$last : "$name"}}} ] )
{ "_id" : "合肥", "last_name" : "BigCat" }
{ "_id" : "大理", "last_name" : "段王爷" }
{ "_id" : "桃花岛", "last_name" : "黄药师" }
{ "_id" : "蒙古", "last_name" : "华筝" }
将所有文档按gender 进行分组,再统计不同分组的 hometown,并保存到 all_hometown,返回列表
> db.stu.aggregate( [ {$group : {_id : "$gender", all_hometown : {$push : "$hometown"} }} ])
{ "_id" : false, "all_hometown" : [ "桃花岛", "蒙古" ] }
{ "_id" : true, "all_hometown" : [ "蒙古", "桃花岛", "大理", "大理", "合肥" ] }
将所有文档按 gender 进行分组,再统计不同分组的所有数据,并保存到 all_data 里,返回列表
> db.stu.aggregate( [ {$group : {_id : "$gender", all_data : {$push : "$$ROOT"}}} ] )
-------- $match
作用是根据条件进行查询,并返回查询结果,做为后面管道的数据。
一般是配合 $group 一起使用。
1.$match 先取出所有年龄小于等于20的文档,2.再将文档数据按gender进行分组,得出各个分组的所有name
> db.stu.aggregate([
{$match : {age : {$lte : 20}}},
{$group : {_id : "$gender", all_name : {$push : "$name"}}}
])
得出所有 桃花岛或大理的 男性和女性的名字。
> db.stu.aggregate([
{$match : {hometown : {$in : ["桃花岛", "大理"]}}},
{$group : {_id : "$gender", all_name : {$push : "$name"}}}
])
----------------$project
得出所有 桃花岛或大理的 男性和女性的年龄平均值,并只显示 avg_age字段的值,_id 不显示。
> db.stu.aggregate([
{$match : {hometown : {$in : ["桃花岛", "大理"]}}},
{$group : {_id : "$gender", avg_age : {$avg : "$age"}}},
{$project : {_id : 0, avg_age : 1}}
])
------------ $sort
1.$match : 查找所有age小于45的文档
2.$group ; 按hometown进行分组,并得出各个分组的age平均值
3.$sort ;将 avg_age 按降序排序
4.$project :投影显示指定字段
> db.stu.aggregate( [{$match : {age : {$lt : 45}}}, {$group : {_id : "$hometown", avg_age : {$avg : "$age"}}}, {$sort : {avg_age : -1}}, {$project : {_id : 0, avg_age : 1}}])
{ "avg_age" : 29 }
{ "avg_age" : 19 }
{ "avg_age" : 18 }
{ "avg_age" : 16 }
> db.stu.aggregate( [{$match : {age : {$lt : 45}}}, {$group : {_id : "$hometown", avg_age : {$avg : "$age"}}}, {$sort : {avg_age : -1}}, {$project : {_id : 1, avg_age : 1}}])
{ "_id" : "桃花岛", "avg_age" : 29 }
{ "_id" : "蒙古", "avg_age" : 19 }
{ "_id" : "合肥", "avg_age" : 18 }
{ "_id" : "大理", "avg_age" : 16 }
> db.stu.aggregate([
{$match : {age : {$lt : 45}}},
{$group : {_id : "$hometown", avg_age : {$avg : "$age"}}},
{$sort : {avg_age : -1}},
{$project : {_id : 1, avg_age : 1}},
{$skip : 1},
{$limit : 2}
])
将所有文档按 gender 进行分组,并统计每个分组的所有 name 的值,$push 返回列表
> db.stu.aggregate([ {$group : {_id : "$gender", all_name : {$push : "$name"}}}])
{ "_id" : false, "all_name" : [ "黄蓉", "华筝" ] }
{ "_id" : true, "all_name" : [ "郭靖", "黄药师", "段誉", "段王爷", "BigCat" ] }
> db.stu.find()
{ "_id" : 1, "name" : "郭靖", "hometown" : "蒙古", "age" : 20, "gender" : true }
{ "_id" : 2, "name" : "黄蓉", "hometown" : "桃花岛", "age" : 18, "gender" : false }
{ "_id" : 3, "name" : "华筝", "hometown" : "蒙古", "age" : 18, "gender" : false }
{ "_id" : 4, "name" : "黄药师", "hometown" : "桃花岛", "age" : 40, "gender" : true }
{ "_id" : 5, "name" : "段誉", "hometown" : "大理", "age" : 16, "gender" : true }
{ "_id" : 6, "name" : "段王爷", "hometown" : "大理", "age" : 45, "gender" : true }
{ "_id" : 7, "name" : "BigCat", "hometown" : "合肥", "age" : 18, "gender" : true }
$unwind ; 将数组进行拆分,得出每个元素,并单独保存为一个文档。
> db.stu.aggregate([
{$group : {_id : "$gender", all_name : {$push : "$name"}}},
{$unwind : "$all_name"}
])
{ "_id" : false, "all_name" : "黄蓉" }
{ "_id" : false, "all_name" : "华筝" }
{ "_id" : true, "all_name" : "郭靖" }
{ "_id" : true, "all_name" : "黄药师" }
{ "_id" : true, "all_name" : "段誉" }
{ "_id" : true, "all_name" : "段王爷" }
{ "_id" : true, "all_name" : "BigCat" }
使用aggregate聚合查询重复数据
- $group中是查询条件,根据content、endTime、startTime字段来聚合相同的数据;
- $count用来统计重复出现的次数, $match来过滤没有重复的数据;
- $addToSet将聚合的数据id放入到dups数组中方便后面使用;
查询结果使用forEach进行迭代id来删除数据
1. shift()作用是剔除队列中第一条id,避免删掉所有的数据;
db.Passages.aggregate([
{
$group:{_id:{content:'$content',endTime:'$endTime',startTime:'$startTime'},count:{$sum:1},dups:{$addToSet:'$_id'}}
},
{
$match:{count:{$gt:1}}
}
]).forEach(function(it){
it.dups.shift();
db.Passages.remove({_id: {$in: it.dups}});
});
-------------- 索引:
1.查看查询的执行状态
db.data.find({name : “user12345”}).explain(“executionStats”)
2._id 默认是集合的索引,可以极大的提高查询速度
db.data.find({_id : 12345}).explain(“executionStats”)
3.如果不想通过_id做为查询,可以设置自定义字段做为索引
db.data.ensureIndex({name : 1})
4.查看当前集合的所有索引
db.data.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.data"
},
{
"v" : 1,
"key" : {
"name" : 1
},
"name" : "name_1",
"ns" : "test.data"
}
]
每个索引都会对应一个 name 字段,表示索引名
5.根据name字段进行删除索引
db.data.dropIndex("name_1")
------------- MongoDB 的数据备份和恢复
备份:将MongoDB数据备份到磁盘文件中
将 -h 指定的MongoDB 服务器 的 -d 指定的 数据库数据,备份到 -o 指定的目录里
sudo mongodump -h 192.168.64.91 -d Tencent -o /data/TencentData
恢复:将磁盘文件的数据恢复到MongoDB里
将 --dir 指定的文件数据,恢复到 -h 指定的MongoDB数据库里,并 -d 指定数据库名称
sudo mongorestore -h 192.168.64.130 -d Tencent --dir /data/TencentData/Tencent