likes
comments
collection
share

「MongoDB」基础操作

作者站长头像
站长
· 阅读数 22

本文主要会介绍一些关于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的有关基础操作就先总结到这儿啦~ 主要是还没整理这一块的知识点,自己的知识库都成一团了,就不发出来误导大家了 如果对你有帮助的话,就让我看到吧🎈

转载自:https://juejin.cn/post/7168770573118504991
评论
请登录