「MongoDB」基础操作

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 本文主要会介绍一些关于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
相关文章
|
6月前
|
存储 NoSQL MongoDB
学习如何使用 Python 连接 MongoDB: PyMongo 安装和基础操作教程
Python 需要一个 MongoDB 驱动程序来访问 MongoDB 数据库。我将使用 MongoDB 驱动程序 PyMongo 建议您使用 PIP 来安装 PyMongo。PIP 很可能已经安装在您的 Python 环境中。将命令行导航到 PIP 的位置,然后键入以下内容:
164 1
|
6月前
|
存储 NoSQL 关系型数据库
Mongo DB 安装及基础操作
MongoDB是一种开源的、基于文档的NoSQL数据库管理系统。它是由10gen(现为MongoDB Inc.)开发和维护的。MongoDB的设计目标是提供灵活的、可扩展的数据存储解决方案,适用于各种类型的应用程序。
295 2
|
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
3832 0
|
1月前
|
存储 关系型数据库 MySQL
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB区别,适用场景
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB——特点、性能、扩展性、安全性、适用场景比较
|
2月前
|
存储 NoSQL 关系型数据库
非关系型数据库-MongoDB技术(二)
非关系型数据库-MongoDB技术(二)
|
2月前
|
NoSQL 关系型数据库 MongoDB
非关系型数据库-MongoDB技术(一)
非关系型数据库-MongoDB技术(一)
|
11天前
|
NoSQL Cloud Native atlas
探索云原生数据库:MongoDB Atlas 的实践与思考
【10月更文挑战第21天】本文探讨了MongoDB Atlas的核心特性、实践应用及对云原生数据库未来的思考。MongoDB Atlas作为MongoDB的云原生版本,提供全球分布式、完全托管、弹性伸缩和安全合规等优势,支持快速部署、数据全球化、自动化运维和灵活定价。文章还讨论了云原生数据库的未来趋势,如架构灵活性、智能化运维和混合云支持,并分享了实施MongoDB Atlas的最佳实践。
|
12天前
|
NoSQL Cloud Native atlas
探索云原生数据库:MongoDB Atlas 的实践与思考
【10月更文挑战第20天】本文探讨了MongoDB Atlas的核心特性、实践应用及对未来云原生数据库的思考。MongoDB Atlas作为云原生数据库服务,具备全球分布、完全托管、弹性伸缩和安全合规等优势,支持快速部署、数据全球化、自动化运维和灵活定价。文章还讨论了实施MongoDB Atlas的最佳实践和职业心得,展望了云原生数据库的发展趋势。