本文正在参与「技能专题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~