本文正在参与「技能专题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中默认包括数据库adminconfiglocaltest,但是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 会主动创立调集。

一个:

「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

条件查询

关于条件,这儿只介绍了andorinnin,具体语法如下:

# 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}}}])

「MongoDB」基础操作

「MongoDB」基础操作

$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"}}}])

「MongoDB」基础操作

$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键值对,并将keyvalue输出到reduce函数中;reduce主要是将key-values变为key-value

querysortlimit都是在送入到map之前进行的操作。

事例:在调集orders中查找status:"A"的数据,,并依据cust_id分组,核算amount的和。

「MongoDB」基础操作

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~