什么是MongoDB ?
MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负荷的情况下,添加更多的节点,可以保证服务器性能。
MongDB将数据存储为一个文档,数据结构由键值对(key=>value)组成。MongDB文档类似于JSON对象。
字段值可以包含其他文档,数组等。
主要特点
MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
MongoDB安装简单。
MongoDB的下载及安装
你可以在mongodb的官网下载相应的安装包,地址为:网址:https://www.mongodb.com/download-center/community。如下图所示:
下载 相应的.msi 文件,下载后双击该文件,按操作提示安装即可。
安装过程中,你可以通过点击 “Custom(自定义)” 按钮来设置你的安装目录,也可以通过点击"Complete"按钮进行完整安装。如下图:
data目录是数据存储目录,数据库中的数据就存储在这个目录中。log是日志文件的输出目录。
下一步安装"install mongoDB compass"不勾选(当然你也可以选择安装它,可能需要更久的安装时间),MongoDB Compass 是一个图形界面管理工具,我们可以在后面自己到官网下载安装,下载地址:https://www.mongodb.com/download-center/compass。
命令行下运行 MongoDB 服务器
为了从命令提示符下运行 MongoDB 服务器,你可以从 MongoDB 目录的 bin 目录中执行 mongod.exe 文件,也可以将文件路径加入到path环境变量中,然后在命令行调用mongo。执行成功后,会输出以下信息:
这样也就进入了mongo的交互环境。由于它是一个JavaScript shell,您可以运行一些简单的算术运算:
MongoDB 概念解析
不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍。
MongoDB的操作
MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
下面我们通过命令创建数据库student:
> use student
switched to db runoob
> db
student
如果你想查看所有数据库,可以使用 show dbs 命令:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
可以看到,我们刚创建的数据库 student 并不在数据库的列表中, 要显示它,我们需要向该数据库插入一些数据。(创建数据表/集合)
> db.student.insert({'name':'张三','age':16})
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
student 0.000GB
MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
删除数据库
MongoDB 删除数据库的语法格式如下:
db.dropDatabase()
删除当前数据库,默认为test,可以使用 db 命令来查看当前数据库名。
创建集合(数据表)
MongoDB 中使用 createCollection() 方法来创建集合。
语法格式:
db.createCollection(name, options)
参数说明:
name: 要创建的集合名称
options: 可选参数, 指定有关内存大小及索引的选项
options 可以是如下参数:
capped:布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
size:数值 (可选)为固定集合指定一个最大值,即字节数。如果 capped 为 true,也需要指定该字段。
max:数值 (可选)指定固定集合中包含文档的最大数量。
在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。
实例
在 test 数据库中创建 runoob 集合:
如果要查看已有集合,可以使用 show collections 或 show tables 命令:
在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
删除集合
语法如下:
db.collection.drop()
返回值
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
在集合中插入文档
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
save():如果 _id 主键存在则更新数据,如果不存在就插入数据。
insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
MongoDB 更新文档
MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。
update() 方法
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
}
)
参数说明:
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如
,
,
,inc…)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
实例
我们在集合 col 中插入如下数据:
db.col.insert({
title: ‘MongoDB 教程’,
description: ‘MongoDB 是一个 Nosql 数据库’,
by: ‘菜鸟教程’,
url: ‘http://www.runoob.com’,
tags: [‘mongodb’, ‘database’, ‘NoSQL’],
likes: 100
})
接着我们通过 update() 方法来更新标题(title):
db.col.update({‘title’:‘MongoDB 教程’},{$set:{‘title’:‘MongoDB’}})
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 }) # 输出信息
db.col.find().pretty()
{
“_id” : ObjectId(“56064f89ade2f21f36b03136”),
“title” : “MongoDB”,
“description” : “MongoDB 是一个 Nosql 数据库”,
“by” : “菜鸟教程”,
“url” : “http://www.runoob.com”,
“tags” : [
“mongodb”,
“database”,
“NoSQL”
],
“likes” : 100
}
可以看到标题(title)由原来的 “MongoDB 教程” 更新为了 “MongoDB”。
以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。
db.col.update({‘title’:‘MongoDB 教程’},{$set:{‘title’:‘MongoDB’}},{multi:true})
save() 方法
save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入。
MongoDB 删除文档
语法格式如下:
db.collection.remove(
,
{
justOne: ,
}
)
参数说明:
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
# 删除所有满足条件的数据
db.stu.remove({'age:{$gt:18}})
# 删除满足条件的第一条数据
db.stu.remove({'age:{$gt:18}},1)
db.stu.remove({'age:{$gt:18}},{justOne:true])
如果你想删除所有数据,可以使用以下方式
db.col.remove({})
MongoDB 查询文档
MongoDB 查询文档使用 find() 方法,语法格式如下:
db.collection.find(query, projection)
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
db.col.find().pretty()
pretty() 方法以格式化的方式来显示所有文档。
除了find()方法之外,还有一个findOne()方法,它返回一个文档。
MongoDB 与 RDBMS Where 语句比较
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:
MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
语法格式如下:
db.col.find({key1:value1, key2:value2}).pretty()
MongoDB OR 条件
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
db.stu.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
MongoDB 条件操作符
条件操作符用于比较两个表达式并从mongoDB集合中获取数据。
MongoDB中条件操作符有:
(>) 大于 - $gt
(<) 小于 - $lt
(>=) 大于等于 - $gte
(<= ) 小于等于 - $lte
MongoDB 使用 (<) 和 (>) 查询 - $lt 和 $gt
如果你想获取"col"集合中 “likes” 大于100,小于 200 的数据,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
MongoDB 进阶知识
MongoDB Limit与Skip方法
MongoDB Limit() 方法
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
limit()方法基本语法如下所示:
db.COLLECTION_NAME.find().limit(NUMBER)
注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据。
MongoDB Skip() 方法
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
skip() 方法脚本语法格式如下:
db.COLLECTION_NAME.find().skip(NUMBER)
MongoDB 排序
在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。(字符串也可以比较)
sort()方法基本语法如下所示:
db.COLLECTION_NAME.find().sort({KEY:1})
MongoDB 索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
createIndex() 方法
MongoDB使用 createIndex() 方法来创建索引。
createIndex()方法基本语法格式如下所示:
db.collection.createIndex(keys, options)
语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
在后台创建索引:
db.values.createIndex({open: 1, close: 1}, {background: true})
通过在创建索引时加 background:true 的选项,让创建工作在后台执行
1、查看集合索引
db.col.getIndexes()
2、查看集合索引大小
db.col.totalIndexSize()
3、删除集合所有索引
db.col.dropIndexes()
4、删除集合指定索引
db.col.dropIndex(“索引名称”)
MongoDB 聚合
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似 SQL 语句中的 count(*)。
MongoDB中聚合的方法使用aggregate():
aggregate() 方法的基本语法格式如下所示:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
实例
集合中的数据如下:
{
"_id" : ObjectId("60e819e23039ea1b9aedfee5"),
"name" : "jim",
"age" : 25,
"email" : "75431457@qq.com",
"c" : 89,
"m" : 96,
"e" : 87,
"country" : "USA",
"books" : [
"JS",
"C++",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfee6"),
"name" : "tom",
"age" : 25,
"email" : "214557457@qq.com",
"c" : 75,
"m" : 66,
"e" : 97,
"country" : "USA",
"books" : [
"PHP",
"JAVA",
"EXTJS",
"C++"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfee7"),
"name" : "lili",
"age" : 26,
"email" : "344521457@qq.com",
"c" : 75,
"m" : 63,
"e" : 97,
"country" : "USA",
"books" : [
"JS",
"JAVA",
"C#",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfee8"),
"name" : "zhangsan",
"age" : 27,
"email" : "2145567457@qq.com",
"c" : 89,
"m" : 86,
"e" : 67,
"country" : "China",
"books" : [
"JS",
"JAVA",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfee9"),
"name" : "lisi",
"age" : 26,
"email" : "274521457@qq.com",
"c" : 53,
"m" : 96,
"e" : 83,
"country" : "China",
"books" : [
"JS",
"C#",
"PHP",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfeea"),
"name" : "wangwu",
"age" : 27,
"email" : "65621457@qq.com",
"c" : 45,
"m" : 65,
"e" : 99,
"country" : "China",
"books" : [
"JS",
"JAVA",
"C++",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfeeb"),
"name" : "zhaoliu",
"age" : 27,
"email" : "214521457@qq.com",
"c" : 99,
"m" : 96,
"e" : 97,
"country" : "China",
"books" : [
"JS",
"JAVA",
"EXTJS",
"PHP"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfeec"),
"name" : "piaoyingjun",
"age" : 26,
"email" : "piaoyingjun@uspcat.com",
"c" : 39,
"m" : 54,
"e" : 53,
"country" : "Korea",
"books" : [
"JS",
"C#",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfeed"),
"name" : "lizhenxian",
"age" : 27,
"email" : "lizhenxian@uspcat.com",
"c" : 35,
"m" : 56,
"e" : 47,
"country" : "Korea",
"books" : [
"JS",
"JAVA",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfeee"),
"name" : "lixiaoli",
"age" : 21,
"email" : "lixiaoli@uspcat.com",
"c" : 36,
"m" : 86,
"e" : 32,
"country" : "Korea",
"books" : [
"JS",
"JAVA",
"PHP",
"MONGODB"
]
}
{
"_id" : ObjectId("60e819e23039ea1b9aedfeef"),
"name" : "zhangsuying",
"age" : 22,
"email" : "zhangsuying@uspcat.com",
"c" : 45,
"m" : 63,
"e" : 77,
"country" : "Korea",
"books" : [
"JS",
"JAVA",
"C#",
"MONGODB"
]
}
现在我们通过以上集合计算每个年龄的人数,使用aggregate()计算结果如下:
db.stu.aggregate([{$group:{_id:'$age',num:{$sum:1}}}])
{ "_id" : 21, "num" : 1 }
{ "_id" : 22, "num" : 1 }
{ "_id" : 27, "num" : 4 }
{ "_id" : 26, "num" : 3 }
{ "_id" : 25, "num" : 2 }
在上面的例子中,我们通过字段 age 字段对数据进行分组,并计算 age 字段相同值的总和。
下图展示了一些聚合的表达式:
管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域。
$ match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
管道操作符实例
1、$project实例
db.article.aggregate(
{ $project : {
title : 1 ,
author : 1 ,
}}
)
这样的话结果中就只还有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
db.article.aggregate(
{ $project : {
_id : 0 ,
title : 1 ,
author : 1
}})
2.$match实例
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] )
m a t c h 用 于 获 取 分 数 大 于 70 小 于 或 等 于 90 记 录 , 然 后 将 符 合 条 件 的 记 录 送 到 下 一 阶 段 match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段 match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段group管道操作符进行处理。
3.$skip实例
db.article.aggregate(
{ $skip : 5 })
经过$skip管道操作符处理后,前五个文档被"过滤"掉。