mongoDB介绍
MongoDB是一个基于分布式文件存储 的数据库。由C++语言编写。它的特点是高性能、易部署、易使用,存储数据非常方便。
功能特性
- 面向集合存储,容易存储对象类型的数据
- 模式自由,采用无模式结构存储
- 支持完全索引,可以在任意属性上建立索引,包含内部对象
- 支持查询
- 强大的聚合工具
- 支持复制和数据恢复
- 使用高效的二进制数据存储,包括大型对象(如视频)
- 自动处理分片,以支持云计算层次的扩展
- 文件存储格式为BSON(JSON 的一种扩展)
- 可以通过网络访问
mongoDB 4.0.2及之后的版本才支持事务。
基本概念
文档
文档是 MongoDB 中数据的基本单位,类似于关系数据库中的行(但是比行复杂)。多个键及其关联的值有序地放在一起就构成了文档。
集合
集合就是一组文档,类似于关系数据库中的表。集合是无模式的,集合中的文档可以是各式各样的。例如,{“hello,word”:“Mike”}和{“foo”: 3},它们的键不同,值的类型也不同,但是它们可以存放在同一个集合中,也就是不同模式的文档都可以放在同一个集合中。
数据库
MongoDB 中多个文档组成集合,多个集合组成数据库。一个MongoDB 实例可以承载多个数据库。它们之间可以看作相互独立,每个数据库都有独立的权限控制。在磁盘上,不同的数据库存放在不同的文件中。MongoDB 中存在以下系统数据库。
- Admin 数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin 数据库中,那么该用户就自动继承了所有数据库的权限。
- Local 数据库:这个数据库永远不会被复制,可以用来存储本地单台服务器的任意集合。
- Config 数据库:当MongoDB 使用分片模式时,config 数据库在内部使用,用于保存分片的信息。
数据模型
一个MongoDB 实例可以包含一组数据库,一个DataBase 可以包含一组Collection(集合),一个集合可以包含一组Document(文档)。一个Document包含一组field(字段),每一个字段都是一个key/value pair。 key: 必须为字符串类型。 value:可以包含如下类型。
- 基本类型,例如,string,int,float,timestamp,binary 等类型。
- 一个document。
- 数组类型。
mongoDB基本用法
查询
基本查询格式如下
db.collection.find(query, projection);
db.collection.findOne(query, projection);
query :可选,使用查询操作符指定查询条件 projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。 如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
db.col.find().pretty();
pretty() 方法以格式化的方式来显示所有文档。
以下是与常规的sql语法比较
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
语法格式如下:
db.col.find({key1:value1, key2:value2}).pretty()
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
更新
MongoDB 使用 update() 和 save() 方法来更新集合中的文档。 update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
参数说明:
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如
,
,
,inc…)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入新文档,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入。语法格式如下:
db.col.save({
"_id" : ObjectId("56064f89ade2f21f36b03136"),
"title" : "MongoDB",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "Runoob",
"url" : "http://www.baidu.com",
"tags" : [
"mongodb",
"NoSQL"
],
"likes" : 110
})
批量更新还有一个方法,更高效点,就是updateMany。语法格式如下
db.collection.updateMany(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
- filter 筛选条件
- update : update的对象和一些更新的操作符(如 $set, $unset, or $rename.)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入新文档,true为插入,默认是false,不插入。避免插入多条数据,要保证filter的字段是创建了唯一索引。
- writeConcern:可选的。 表达写关注的文件。 省略使用默认写关注。如果在事务中运行,请不要显式设置操作的写关注。
- collation:指定用于操作的排序规则。排序规则允许用户为字符串比较指定特定于语言的规则,例如字母和重音符号的规则。
排序规则选项具有以下语法:
collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}
指定排序规则时,locale 字段是必需的; 所有其他整理字段都是可选的。 如果未指定排序规则但集合具有默认排序规则(请参阅 db.createCollection()),则操作使用为集合指定的排序规则。 如果没有为集合或操作指定排序规则,MongoDB 使用先前版本中使用的简单二进制比较进行字符串比较。您不能为一个操作指定多个排序规则。 例如,您不能为每个字段指定不同的排序规则,或者如果使用排序执行查找,即不能使用一种排序规则进行查找,而使用另一种排序规则进行排序。
- arrayFilters:可选的。 一个过滤器文档数组,用于确定要为数组字段的更新操作修改哪些数组元素。在更新文档中,使用 $[] 过滤位置运算符定义一个标识符,然后在数组过滤器文档中引用该标识符。 如果标识符未包含在更新文档中,则您不能拥有标识符的数组过滤器文档。
格式如下:
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]
删除
MongoDB remove() 函数是用来移除集合中的数据。
MongoDB 数据更新可以使用 update() 函数。在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确,这是一个比较好的习惯。 remove() 方法的基本语法格式如下所示:
db.collection.remove(
<query>,
<justOne>
)
2.6 版本以后的,语法格式如下:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
参数说明:
- query :(可选)删除的文档的条件。
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。
插入
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
- save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne() 或db.collection.replaceOne() 来代替。
- insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。
|