本文正在参与「技能专题19期 闲谈数据库技能」活动
关于MongoDB最新版别在Win10/11系统的上的装置教程,你能够参阅我之前的文章 -> 「MongoDB」Win10版装置教程 这儿就不再赘述了~
本文主要会介绍一些关于MongoDB数据库的根本操作:
- 数据库相关
- 数据的导入、导出
- 调集操作
- 文档操作
- 关于游标
- 管道聚合操作
假如感兴趣的话,就往下看吧~
数据库操作
装好数据库之后,假如你在Linux环境下,就能够用下面两条指令检查mongodb的服务是否发动以及衔接到mongo。但是注意假如你是win10的话,并且装置的mongodb版别是最新版别的,需求下载mongoshell才能够进到交互式的环境,至于翻开服务的话就到使命管理器-》服务->找到Mongod就行(也许叫MongoDB,
一下忘了)
pgrep mongo -l # 检查mongodb是否现已发动
mongo # 衔接mongo
本文版别是
MongoDB shell version v4.0.0
数据库的根本操作:(创立、删去、检查、刺进数据,包罗万象)
use Testdb # 创立数据库
db.Testdb.insert({_id:1,name:"王小明"}) # 刺进数据
# 循环向调集items刺进数据
for(var i = 0; i < 10000; i++) db.items.insert({_id:i, text:"Hello" + i})
db # 检查当时数据库
show dbs # 检查一切数据库
# 删去数据库 -- MongoDB 删去数据库需求先切换到该数据库中,然后再履行删去指令.
use Testdb
db.dropDatabase()
use Testdb之后show dbs是显现不出Testdb数据库的,由于运用use指令创立的Testdb存储在内存中,且数据库中没有数据,履行insert句子之后再show dbs就能看到Testdb了。
MongoDB中默认包括数据库admin、config、local、test,但是test数据库存储在内存中,也无任何数据,所以履行show dbs也是看不到的。
由于 mongodb 底层是 javascript 引擎,所以我们能够运用 js 的语法来刺进数据。
数据导入、导出
mongoimport
将数据(csv/ json等)导入mongodb数据,用到的指令是mongoimport,
具体语法如下:
# 导入- mongoimport
mongoimport -d Testdb1 -c score --type csv --headerline --ignoreBlanks --file test.csv
-d Testdb1 :指定将数据导入到 Testdb1 数据库;
-c score :将数据导入到调集 score ,假如这个调集之前不存在,会主动创立一个(假如省掉 –collection 这个参数,那么会主动新建一个以 CSV 文件名为名的调集);
--type csv :文件类型,这儿是 CSV;
--headerline :这个参数很重要,加上这个参数后创立完成后的内容会以 CSV 文件榜首行的内容为字段名(导入json文件不需求这个参数);
--ignoreBlanks :这个参数能够忽略掉 CSV 文件中的空缺值(导入json文件不需求这个参数);
--file test.csv :这儿便是 CSV 文件的途径了,需求运用肯定途径。
mongoexport
数据导出-mongoexport
具体语法如下:
# 导出为csv -f :当输出格局为 csv 时,有必要指定输出的字段名。
mongoexport -d Testdb1 -c score -o /file.json --type csv -f "_id,name,age,sex,major"
# 导出为json
mongoexport -d Testdb1 -c score -o /file.json --type json
-o /file.json :输出的文件途径/(根目录下)和文件名;
--type json :输出的格局,默以为 json。
调集操作
根本操作:CRUD
# 在 Testdb 数据库中创立创立固定调集 test ,整个调集空间巨细512000KB,文档最大个数为1000个。
use Testdb
# 检查当时数据库一切调集
show collections
# 显式创立调集
db.createCollection("test", { capped : true, autoIndexId : true, size : 512000, max : 1000 } )
# capped :是一个布尔类型,true 时创立固定调集,有必要指定 size。
# 固定调集指有固定巨细的调集,当达到最大值时,它会主动掩盖最早的文档。默以为 false;
# autoIndexId :也是一个布尔类型,如为 true,主动在_id 字段创立索引。默以为 false ;
# size :为固定调集指定一个最大值(以字节 KB 计);
# max :指定固定调集中包括文档的最大数量。
# 隐式创立调集 -- db.调集名.insert()
db.mytest2.insert([{"name" : "王小明","sex":"男"}, {"name" : "李小红","sex":"女"}])
db.调集名.find() # 查询调集
db.调集名.drop() # 删去调集
和 MySQL 不同的是,在 MongoDB 中,你不必定需求先创立调集。当你刺进一些文档时,MongoDB 会主动创立调集。
一个:
文档操作
前面是对调集这个对象进行操作,接下来,就需求对调集中的数据进行操作了~
增修正
一切存储在调集中的数据都是 BSON 格局。BSON 是一种类 JSON 的一种二进制方式的存储格局,简称: Binary JSON 。
document=({_id:1, name: '王小明', sex: '男',hobbies: ['乒乓球','羽毛球'], birthday: '1996-02-14'});
# 刺进
db.调集名.insert(document) # document能够是一个变量
db.collection.insertMany([{},{},...])
# 更新
db.person2.update({birthday:"1996-02-14"},{$set:{birthday:"1996"}})
# update中两个参数,都是对象
# 检查
db.person2.find().pretty() # pretty() 方法的作用是使文档整齐的输出
# 替换 save() 适用修正整条数据
db.person3.save({ "_id" :1, "name" : "李小红", "sex" : "女", "hobbies" : [ "画画", "歌唱", "跳舞" ],"birthday" : "1996-06-14"})
# 删去
db.collection.remove({"name":"www"})
# 删去一切数据,但是调集不会删去
db.remove({})
# 删去指定调集里的一切数据
db.stu2.remove({});
tips:
save()
指定了_id,则对文档进行更新;未指定_id则会履行刺进功用,MongoDB 默认主动生成一个不重复的_id。
update()
- criteria-查询条件,
- objNew-更新后的,
- upsert-默认false,在不存在更新文档的情况下,是否刺进objNew,
- multi-默认false,只更新找到的榜首个)
文档查询
在MySQL中,我们经常会对数据进行必定的挑选,就像大部分的人都喜爱美丽小姐姐和英俊小哥哥相同, 在MongoDB中,必定也不能少了这么重要的操作!
一些根本的运算操作感觉和LaTeX的语法有几分相似~
比较运算
| 操作 | 格局 | 事例 | 关系数据库中类似的句子 |
|---|---|---|---|
| 等于 | {:} | db.stu1.find({“name”:”李小红”}).pretty() | where name = ‘李小红’ |
| 小于 | {:{$lt:}} | db.stu1.find({“age”:{$lt:18}}).pretty() | where age < 18 |
| 小于或等于 | {:{$lte:}} | db.stu1.find({“age”:{$lte:18}}).pretty() | where age <= 18 |
| 大于 | {:{$gt:}} | db.stu1.find({“age”:{$gt:18}}).pretty() | where age > 18 |
| 大于或等于 | {:{$gte:}} | db.stu1.find({“age”:{$gte:18}}).pretty() | where age >= 18 |
| 不等于 | {:{$ne:}} | db.stu1.find({“age”:{$ne:18}}).pretty() | where age != 18 |
条件查询
关于条件,这儿只介绍了and, or, in, nin,具体语法如下:
# and
db.col.find({$and:[{k1:v1},{k2:v2}]})
db.stu1.find({"age":20, "sex":"男"}).pretty() # 查询年龄为20且性别为男的文档
# or
db.col.find({$or:[{k1:v1},{k2:v2}]})
# in
db.col.find({k:{$in:[k1,k2]}})
# nin
db.col.find({k:{$nin:[k1,k2]}})
高档查询
| 符号 | 含义 | 举例 |
|---|---|---|
| $all | 匹配一切:$all 会查询满意方括号中一切条件的文档 |
查询其间一切喜爱“歌唱”和“羽毛球”的人db.hobbies.find({hobbies:{$all:["歌唱","羽毛球"]})
|
| $exists |
{$exists:true} 存在{$exists:false}不存在 |
查询 hobbies 调集中存在 age 字段的文档db.test.find({age:{$exists:true}})
|
| $in/ $nin |
$in 包括 $nin不包括 |
查询 age =17 或 age =20的文档db.test.find({age:{$in:[17,20]}})查询 age !=17 且 age !=20 的文档db.test.find({age:{$nin:[17,20]}})
|
| $size | 数组元素个数 | 查询有两个喜好的文档db.hobbies.find({hobbies:{$size:2}})
|
| $mod | 取模运算 | 查询 age 取模7等于4的文档db.hobbies.find({age:{$mod:[7,4]}})
|
| sort() | 1: 升序 -1:降序 | 升序db . collection . find (). sort ({ _id : 1 })
|
| $or | 或查询 | 查询性别 sex 为 男 或年龄 age 为18的文档信息db.student.find({$or:[{sex:"男"},{age:18}]})
|
| $and | 和 | 查询18 < age < 21之间的文档db.student.find({$and:[{age:{$gt:18}},{age:{$lt:21}}]})
|
| $not | 取反 | 查询年龄小于20岁的文档db.student.find({age:{$not:{$gte:20}}})
|
| count() | 回来成果集总数 | db.student.find({major:{$not:/^计.*/}}).count() |
特定类型查询
# 查询姓名不是以韩最初的
db.test.find({name:{$not:/^计.*/}}})
# 查询字段为null的
db.test.find({k:null})
游标
游标不是查询成果,而是查询的回来资源,或许接口。经过这个接口,你能够逐条读取。就像fopen翻开文件,得到一个资源相同,经过资源,能够一行一行的读文件。
# 声明游标
var cursor = db.items.find({_id:{$lte:5}}) # find _id <= 5 的查询成果赋值给cursor
# 打印游标当中的数据信息-4种方式
# 1.
printjson(cursor.next()) # 打印下一条数据 当一切数据都取完后再履行该句子就会报错
# 2.
for(var cursor=db.test.find({_id:{$lte:5}}); cursor.hasNext(); )
{
printjson(cursor.next());
}
# 3.
while(cursor.hasNext()) {
printjson(cursor.next());
};
# 4.
cursor.forEach(function(obj) {printjson(obj)});
# 分页打印
# skip() 越过多少条数据 limit 显现多少条数据
var cursor = db.test.find().skip(7000).limit(10); # 显现id为7000-7009 由于_id从0开端
cursor.forEach(function(obj) {printjson(obj);});
# 取榜首条文档
printjson(cursor.toArray()[0])
管道聚合
官方文档
MongoDB聚合操作包括聚合管道操作和Map-Reduce操作等。
其间聚合管道操作是将文档在一个管道处理完之后,把处理的成果传递给下一个管道进行再次处理;Map-Reduce操作是将调集中的批量文档进行分化处理,然后将处理后的各个成果进行合并输出。
管道操作符
| 操作符 | 作用 |
|---|---|
| $project | 修正输入文档的结构。能够用来重命名、添加或删去域,也能够用于创立核算成果以及嵌套文档 |
| $match | 用于过滤数据,只输出符合条件的文档。$match运用MongoDB的规范查询操作 |
| $limit | 用来限制MongoDB聚合管道回来的文档数 |
| $skip | 在聚合管道中越过指定数量的文档,并回来余下的文档 |
| $unwind | 将文档中的某一个数组类型字段拆分成多条,每条包括数组中的一个值 |
| $group | 将调集中的文档分组,可用于核算成果 |
| $sort | 将输入文档排序后输出 |
管道表达式
| $sum | 核算总和 |
|---|---|
| $avg | 核算平均值 |
| $min | 获取调集中一切文档对应值的最小值 |
| $max | 获取调集中一切文档对应值的最大值 |
| $push | 在成果文档中刺进值到一个数组中 |
| $addToSet | 在成果文档中刺进值到一个数组中,但不创立副本 |
| $first | 依据资源文档的排序获取榜首个文档数据 |
| $last | 依据资源文档的排序获取最终一个文档数据 |
注意:以上操作不会修正调集的内容,只是将调集以指定方式输出。
举例
$project 修正文档结构输出
场景:有时候只需求输出文档中的几列,运用$project进行操作,还能够运用该聚合符对列名重命名
# 只输出作者 author 和学习人数 learning_num 信息 _id默认显现,这儿设置为0不显现 非0为显现
db.educoder.aggregate({$project:{_id:0,author:1,learning_num:1}})
# 重命名为num
db.educoder.aggregate({$project:{course:1,authoe:1,tags:1,num:'$learning_num'}})
注意这儿除了_id:0能够设置为0外,其他的只需求设置需求的列为1即可,不出现的不必设置为0,否则会报错。
$match 挑选文档输出
# 只输出作者为“李暾”的文档
db.educoder.aggregate({$match:{author:'李暾'}})
$limit
db.product.aggregate({$limit:3}).pretty() # 显现前3个文档
$skip
# 越过前4个文档,展示调集 _id之后为4的文档
db.product.aggregate({$skip:4}).pretty()
#越过榜首条,显现前两条,也便是显现第2-3条文档
db.educoder.aggregate([{$skip:1},{$limit:2}])
#显现前两条,越过榜首条,也便是显现第2条文档
db.educoder.aggregate([{$limit:2},{$skip:1}])
$unwind
将文档中的某一个数组类型字段拆分红多条,每条包括数组中的一个值
# 把tags数组里边的值拆开来
db.educoder.aggregate({$unwind:'$tags'})
# 核算每个tags中出现的次数
db.educoder.aggregate([{$unwind:'$tags'},{$group:{_id:'$tags',course_num:{$sum:1}}}])
$group
# 按作者分组,能够核算出当时调集有多少个作者
db.test.aggregate({$group:{_id:'$author'}})
# 依照type类分组,并别离求不同type组的price总额
db.product.aggregate([{$group:{"_id":"$type","price":{$sum:"$price"}}}])
$sort
# 1 升序 -1 降序
db.product.aggregate([{$sort:{"price":-1}}]).pretty() # 依照price降序输出
$sum
# 获取每个作者拥有的实训数量
db.educoder.aggregate([{$group:{_id:'$author',num_course:{$sum:1}}}])
# 每个作者的实训学习总人数learning_sum
db.educoder.aggregate([{$group:{_id:'$author',learning_sum:{$sum:'$learning_num'}}}])
$sum:1表明前面的情况出现一次就加1,$sum:2前面条件每满意一次就加2
$avg
# 每个type的平均价格
db.product.aggregate([{$group:{"_id":"$type","price":{$avg:"$price"}}}])
$min
# 不同type之中的最小值
db.product.aggregate([{$group:{"_id":"$type","price":{$min:"$price"}}}])
$push
# 按type分类并得到每个type中的一切name
db.product.aggregate([{$group:{"_id":"$type","name":{$push:"$name"}}}])
$first \ $last
# 每个type的榜首个
db.product.aggregate([{$group:{"_id":"$type","name":{$first:"$name"}}}]).pretty()
# 每个type的最终一个
db.product.aggregate([{$group:{"_id":"$type","name":{$last:"$name"}}}]).pretty()
map-reduce操作
Map-Reduce操作先将调集中满意query的文档查询出来,然后将这些满意条件的文档输入到Map阶段中,并依照key进行分组,将key相同的文档的value存放到一个数组中,输出到Reduce阶段进行聚合处理。
Map-Reduce具体操作语法如下:
db.collection.mapReduce(
function() {emit(key,value);}, //map 函数
function(key,values) {return reduceFunction}, //reduce 函数
{
out: collection, // 输出调集的姓名
query: document, // 挑选条件,符合条件的才会调用map函数
sort: document, // 发往map函数前给文档排序,能够优化分组机制
limit: number // 发往map函数的文档数量的上限
}
)
map函数调用emit(k,v)方法,遍历调集中的一切文档,回来k-v键值对,并将key和value输出到reduce函数中;reduce主要是将key-values变为key-value。
query、sort、limit都是在送入到map之前进行的操作。
事例:在调集orders中查找status:"A"的数据,,并依据cust_id分组,核算amount的和。
db.orders.mapReduce(
function() {emit(this.cust_id, this.amount);}, # map阶段
function(key, value) {return Array.sum(value)}, # reduce阶段
{
query:{status:"A"}, # query:条件
out:{"order_totals"}, # output:输出调集姓名
}
)
关于mongodb的有关根底操作就先总结到这儿啦~
主要是还没整理这一块的知识点,自己的知识库都成一团了,就不发出来误导我们了假如对你有帮助的话,就让我看到吧
ps:看到的文章访问量,总比C站更有写作的愿望,hhh~





