「MongoDB」基础操作

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: 本文主要会介绍一些关于MongoDB数据库的基本操作:数据库相关、数据的导入、导出、集合操作、文档操作、关于游标、管道聚合操作

「MongoDB」基础操作


本文主要会介绍一些关于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 会自动创建集合。

一个🌰:

1.png


[文档操作]


前面是对集合这个对象进行操作,接下来,就需要对集合中的数据进行操作了~


增删改


所有存储在集合中的数据都是 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}}}])

1.png

1.png

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

1.png

$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的和。

1.png

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的有关基础操作就先总结到这儿啦~
1.png1.png1.png1.png

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
2天前
|
存储 NoSQL MongoDB
学习如何使用 Python 连接 MongoDB: PyMongo 安装和基础操作教程
Python 需要一个 MongoDB 驱动程序来访问 MongoDB 数据库。我将使用 MongoDB 驱动程序 PyMongo 建议您使用 PIP 来安装 PyMongo。PIP 很可能已经安装在您的 Python 环境中。将命令行导航到 PIP 的位置,然后键入以下内容:
101 1
|
NoSQL MongoDB 数据库
|
NoSQL
mongoVUE对mongodb常用的基础操作
<p>一、    <strong>连接mongodb服务端</strong>:</p> <p></p> <p>1、         双击mongoVUE,进入如下图所示界面:</p> <p><img src="http://img.blog.csdn.net/20151217181157465?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv
3788 0
|
2天前
|
存储 NoSQL MongoDB
MongoDB如何创建数据库
MongoDB如何创建数据库
|
2天前
|
存储 NoSQL MongoDB
MongoDB数据库转换为表格文件的Python实现
MongoDB数据库转换为表格文件的Python实现
28 0
|
2天前
|
存储 NoSQL 关系型数据库
Percona XtraBackup是否支持MongoDB数据库备份?
【5月更文挑战第13天】Percona XtraBackup是否支持MongoDB数据库备份?
27 1
|
2天前
|
NoSQL atlas MongoDB
Nosql数据库MongoDB的使用场景
【5月更文挑战第5天】 MongoDB是全球性的多云数据库,可在私有、公共和混合云中运行,提供高可用性、扩展性和合规性。 安全特性包括认证、授权、审计、网络隔离和加密。可提供跨云操作、可视化工具、搜索功能和数据湖支持,适用于现代应用开发,包括边缘数据处理。
29 1
|
2天前
|
JSON NoSQL MongoDB
理解Nosql数据库的mongodb
【5月更文挑战第5天】MongoDB是2009年发布的一款通用型NoSQL数据库,结合了关系模型和NoSQL的优点,适用于各种现代应用。其特点包括图形界面、数据服务、云基础设施集成(AWS, Azure, Google Cloud)。它具备全面的查询能力、ACID事务、可调整的一致性保证,并有多语言驱动及工具,可在任何地方运行。
24 4
|
2天前
|
存储 NoSQL 关系型数据库
【MongoDB 专栏】MongoDB 与传统关系型数据库的比较
【5月更文挑战第10天】本文对比了MongoDB与传统关系型数据库在数据模型、存储结构、扩展性、性能、事务支持、数据一致性和适用场景等方面的差异。MongoDB以其灵活的文档模型、优秀的扩展性和高性能在处理非结构化数据和高并发场景中脱颖而出,而关系型数据库则在事务处理和强一致性上更具优势。两者各有适用场景,选择应根据实际需求来定。随着技术发展,两者正相互融合,共同构建更丰富的数据库生态。
【MongoDB 专栏】MongoDB 与传统关系型数据库的比较