MongoDB
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ak70Ne1J-1652786798071)(MongoDB.assets/1652526836510.png)]
-
百度百科 MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。 总结:mongDB 是一个非关系型文档数据库 历史 -
2009年2月,MongoDB数据库首次在数据库领域亮相,打破了关系型数据库一统天下的局面; -
2010年8月,MongoDB 1.6发布。这个版本最大的一个功能就是Sharding,自动分片2014年12月,MongoDB3.0发布。由于收购了WiredTiger存储引擎,大幅提升了MongoDB的写入性能; -
2015年12月,3.2版本发布,开始支持了关系型数据库的核心功能:关联。你可以一次同时查询多个MongoDB的集合。 -
2016年,MongoDB推出Atlas,在AwS、Azure和GCP上的MongoDB托管服务; -
2017年10月,MongoDB成功在纳斯达克敲钟,成为26年来第一家以数据库产品为主要业务的上市公司; -
2018年6月, MongoDB4.0发布推出ACID事务支持,成为第一个支持强事务的NoSQL数据库; -
2018年–至今,MongoDB已经从一个在数据库领域籍籍无名的"小透明"",变成了话题度和热度都很高的"流量"数据库。
特点
特点
- 面向集合存储,易存储对象类型的数据
- 支持查询,以及动态查询
- 支持RUBY,PYTHON,JAMA,C++,PHP,C#等多种语言
- 文件存储格式为BSON(一种JSON的扩展)
- 支持复制和故障恢复和分片
- 支持事务支持
- 索引、聚合、关联…
应用场景
- 游戏应用:使用云数据库MongoDB作为游戏服务器的数据库存储用户信息。用户的游戏装备、积分等直接以内嵌文档的形式存储,方便进行查询与更新。
- 物流应用:使用云数据库MongoDB存储订单信息,订单状态在运送过程中会不断更新,以云数据库MongoDB内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来,方便快捷且一目了然。
- 社交应用:使用云数据库MongoDB存储用户信息以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。并且,云数据库MongoDB非常适合用来存储聊天记录,因为它提供了非常丰富的查询,并在写入和读取方面都相对较快。
- 视频直播:使用云数据库MongoDB存储用户信息、礼物信息等。
- 大数据应用:使用云数据库MongoDB作为大数据的云存储系统,随时进行数据提取分析,掌握行业动态。
安装
传统方式
下载连接: Try MongoDB Atlas Products | MongoDB
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UP0nhmXn-1652786798072)(MongoDB.assets/1652535978224.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JiST8VsN-1652786798073)(MongoDB.assets/1652536005323.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zyxQe8QJ-1652786798073)(MongoDB.assets/1652536078235.png)]
解压:
[root@root mongoDB]
mongodb-linux-x86_64-rhel70-5.0.8.tgz
[root@root mongoDB]
[root@root mongoDB]
mongodb-linux-x86_64-rhel70-5.0.8 mongodb-linux-x86_64-rhel70-5.0.8.tgz
[root@root mongoDB]
[root@root mongoDB]
mongodb mongodb-linux-x86_64-rhel70-5.0.8.tgz
[root@root mongoDB]
查看目录中的信息
[root@root mongoDB]
[root@root mongodb]
bin LICENSE-Community.txt MPL-2 README THIRD-PARTY-NOTICES
[root@root mongodb]
总用量 132
drwxr-xr-x. 2 root root 70 5月 14 09:48 bin
-rw-r--r--. 1 root root 30608 4月 21 17:15 LICENSE-Community.txt
-rw-r--r--. 1 root root 16726 4月 21 17:15 MPL-2
-rw-r--r--. 1 root root 1977 4月 21 17:15 README
-rw-r--r--. 1 root root 76823 4月 21 17:15 THIRD-PARTY-NOTICES
[root@root mongodb]
[root@root bin]
install_compass mongo mongod mongos
[root@root bin]
总用量 238632
-rwxr-xr-x. 1 root root 15205 4月 21 17:15 install_compass
-rwxr-xr-x. 1 root root 58460872 4月 21 18:01 mongo
-rwxr-xr-x. 1 root root 109480888 4月 21 18:02 mongod
-rwxr-xr-x. 1 root root 76396488 4月 21 17:40 mongos
启动MongoDB
[root@root bin]
[root@root bin]
[root@root bin]
bin data LICENSE-Community.txt logs MPL-2 README THIRD-PARTY-NOTICES
./mongod --port=27017 --dbpath=../data --logpath=../logs/mongo.log
查看是否开启成功
[root@root bin]
MongoDB shell version v5.0.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("e7163a03-f323-4148-b616-a0894230e671") }
MongoDB server version: 5.0.8
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
https://community.mongodb.com
---
The server generated these startup warnings when booting:
2022-05-14T10:11:28.080-04:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
2022-05-14T10:11:28.080-04:00: You are running this process as the root user, which is not recommended
2022-05-14T10:11:28.080-04:00: This server is bound to localhost. Remote systems will be unable to connect to this server. Start the server with --bind_ip <address> to specify which IP addresses it should serve responses from, or with --bind_ip_all to bind to all interfaces. If this behavior is desired, start the server with --bind_ip 127.0.0.1 to disable this warning
2022-05-14T10:11:28.080-04:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
2022-05-14T10:11:28.080-04:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never'
2022-05-14T10:11:28.080-04:00: Soft rlimits for open file descriptors too low
2022-05-14T10:11:28.080-04:00: currentValue: 1024
2022-05-14T10:11:28.080-04:00: recommendedMinimum: 64000
---
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
> show dbs;
admin 0.000GB
config 0.000GB
local 0.000GB
>
docker版:
sudo systemctl start docker
docker pull mongo:5.0.8
docker run --name mongo -d -p 27017:27017 mongo:5.0.8
查看运行状态:
[root@root bin]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efd8986d6ee8 mongo:5.0.8 "docker-entrypoint.s…" 9 seconds ago Up 8 seconds 0.0.0.0:27017->27017/tcp, :::27017->27017/tcp mongo
[root@root bin]
进入容器内部:
[root@root bin]
root@efd8986d6ee8:/
MongoDB shell version v5.0.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
{"t":{"$date":"2022-05-14T15:02:55.808Z"},"s":"I", "c":"NETWORK", "id":5693100, "ctx":"js","msg":"Asio socket.set_option failed with std::system_error","attr":{"note":"connect (sync) TCP fast open","option":{"level":6,"name":30,"data":"01 00 00 00"},"error":{"what":"set_option: Protocol not available","message":"Protocol not available","category":"asio.system","value":92}}}
Implicit session: session { "id" : UUID("bdead5f3-d99c-45f8-a065-c6f020e99063") }
MongoDB server version: 5.0.8
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
https://community.mongodb.com
---
The server generated these startup warnings when booting:
2022-05-14T14:56:02.063+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
2022-05-14T14:56:02.063+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
2022-05-14T14:56:02.063+00:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never'
---
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
>
输入show dbs;
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
停止服务:
docker stop efd8986d6ee8
核心概念
库
==mongodb中的库就类似于传统关系型数据库中库的概念,用来通过不同库隔离不同应用数据。==mongodb中可以建立多个数据库。每一个库都有自己的集合和权限,不同的数据库也放置在不同的文件中。默认的数据库为"test",数据库存储在启动指定的data目录中。
集合
集合就是MongoDB文档组,类似于RDBMS(关系数据库管理系统: RelationalDatabase Management System)中的表的概念。 集合存在于数据库中,一个库中可以创建多个集合。每个集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。
文档
文档集合中一条条记录,是一组键值(key-value)对(即BSON)。MongoDB的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是MongoDB非常突出的特点。
一个简单的文档例子如下:
{ "site" : "li" , "name":"li"}
关系总结
RDBMS | MongoDB |
---|
数据库 | 数据库 | 表
| 集合 | 行 | 文档 | 列 | 字段 |
基本操作
库
> show databases; | show dbs;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dtLZglPJ-1652786798074)(MongoDB.assets/1652586519809.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkcybR2Q-1652786798075)(MongoDB.assets/1652586590882.png)]
注意:
- admin: 从权限的角度来看,这是""root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务
- local : 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config : 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
- 创建数据库
> use 库名
>cls
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wx4d0gk2-1652786798076)(MongoDB.assets/1652586684191.png)]
创建库为什么看不到呢?
因为:在mongodb中如果数据库中没有任何集合(数据)的时候默认这个库不显示,可以通过db来查看当前所在的库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XAblxqo-1652786798076)(MongoDB.assets/1652586856156.png)]
插入数据:
> db.users.insert({name:'li'});
WriteResult({ "nInserted" : 1 })
>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIdkGuOG-1652786798077)(MongoDB.assets/1652590351136.png)]
这个时候就可以看到数据库了
>db.dropDatabase();
集合
> show collections; | show tables;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tm2D4Oxd-1652786798077)(MongoDB.assets/1652591347193.png)]
> db.creatCollection('集合名称',[options])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CXEPAxTD-1652786798078)(MongoDB.assets/1652591429475.png)]
> db.createCollection('products',{max:100,capped:true,size:5000});
{ "ok" : 1 }
>
options可以是如下参数:
字段 | 类型 | 描述 |
---|
capped | 布尔 | (可选)如果为true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为true时,必须指定size参数。 | size | 数值 | (可选)为固定集合指定一个最大值,即字节数。如果capped为true,也需要指定该字段。 | max | 数值 | (可选)指定固定集合中包含文档的最大数量。 |
注意:当集合不存在时,向集合中插入文格也会自动创建该集合。
db.集合名称.drop();
> db.products.drop();
true
>
文档
官方文档地址: MongoDB CRUD Operations — MongoDB Manual
插入文档
-
单条文档 -
db.集合名称.insert( { "name":"li" , " age" :18 , "bir":"2004-5-20"});
-
多条文档 db.集合名称.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: 1,ll写入策略,默认为1,即要求确认写操作,日是不要求。ordered: true l/指定是否按顺序写入,默认true,按顺序写入。
}
)
db.集合名称.insert([
{ "name":"li”, "age" :18 , "bir" : "2004-5-20"},
{ "name" : "ling" , "age" :20, "bir" : "2002-5-20"}
]);
> db.users.insert({name:'li',age:18,bir:'2004-5-20'});
WriteResult({ "nInserted" : 1 })
> db.users.insertMany([{name:'li',age:18},{_id:1,name:'ling',age:21}]);
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("628093fc01acffadf5d96f67"),
1
]
}
> db.users.insert([{name:'li',age:18},{name:'ling',age:21}]);
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
>
脚本方式 for(let i=0;i<100;i++){
db.users.insert( { "_id" :i , " name" :"li_"+i, "age" :23});
}
注意:在mongodb中每个文档都会有一个_id作为唯一标识,_id默认会自动生成如果手动指定将使用手动指定的值作为_id 的值。 -
查询所有
db.集合名称.find();
删除文档
db.集合名称.rexove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
参数说明:
o query :可选删除的文档的条件。 o justOne:可选如果设为true 或1,则只删除一个文档,如果不设置该参数,或使用默认值false,则删除所有匹配条件的文档。 o writeConcern:可选抛出异常的级别。
更新文档
db.集合名称.update(
<query>,
<update>,
{
upsert: <boolean>,
multi : <boolean>,
writeConcern : <document>
}
);
参数说明:
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如s,$inc…)等,也可以理解为sqlupdate查询内set后面
- upsert:可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi :可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
- db.集合名称.update( {"name" :"zhangsan" } , {name :"li",bir:new date()))
- db.集合名称.update( {"name" : "li" },{$set:{name : " ali")})
- db.集合名称.update( {name:"li"},{$set: {name:"ling"}},{multi:true})
- db.集合名称.update( {name :"li"},{$set:{name: "ling"}},{multi:true, upsert:true})
文档查询
MongoDB查询文档使用fixd()方法。find(方法以非结构化的方式来显示所有文档。
语法
db.集合名称.find ( query, projection)
如果你需要以易读的方式来读取数据,可以使用pretty()方法,语法格式如下:
db.集合名称.find ( ) .pretty ()
注意:pretty()方法以格式化的方式来显示所有文档.
对比语法
如果你熟悉常规的sQL 数据,通过下表可以更好的理解MongoDB的条件语句查询:
操作 | 格式 | 范例 | RDBMS中的类似语句 |
---|
等于 | {:} | db.col.find({“by”:“菜鸟教程”}).pretty() | where by = ‘菜鸟教程’ | 小于 | {:{$lt:}} | db.col.find({“likes”:{$lt:50}}).pretty() | where likes < 50 | 小于或等于 | {:{$lte:}} | db.col.find({“likes”:{$lte:50}}).pretty() | where likes <= 50 | 大于 | {:{$gt:}} | db.col.find({“likes”:{$gt:50}}).pretty() | where likes > 50 | 大于或等于 | {:{$gte:}} | db.col.find({“likes”:{$gte:50}}).pretty() | where likes >= 50 | 不等于 | {:{$ne:}} | db.col.find({“likes”:{$ne:50}}).pretty() | where likes != 50 |
AND
>db.col.find({key1:value1, key2:value2,....}).pretty()
类似于wHERE语句:WHERE key1=value1 AND key2=value2
OR
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
类似于WHERE语句:霞ERE key1=value1 or key2=value2
AND和OR联合
db.集合名称.find( {"age": {$gt :50},$or : [{"name”:“li"},{"name" :
"MongoDB"}]}).pretty(o):
类似SQL语句为: "where age >50 AND(name =“li’OR name = ’ MongoDB’)
数组中查询
> db.集合名称.insert({ "_id" : 11, "age" : 22, "likes" : [ "ling", "li" ], "name" : "li_11" })
> db.users.find({likes:"ling"})
{ "_id" : 11, "age" : 22, "likes" : [ "ling", "li" ], "name" : "li_11" }
模糊查询
类似于SQL中为 where name like ‘%name%’
> db.users.find({name:/li/});
{ "_id" : 0, "name" : "li_0", "age" : 18 }
{ "_id" : 1, "name" : "li_1", "age" : 18 }
{ "_id" : 2, "name" : "li_2", "age" : 18 }
{ "_id" : 3, "name" : "li_3", "age" : 18 }
{ "_id" : 4, "name" : "li_4", "age" : 18 }
{ "_id" : 5, "name" : "li_5", "age" : 18 }
{ "_id" : 6, "name" : "li_6", "age" : 18 }
{ "_id" : 7, "name" : "li_7", "age" : 18 }
{ "_id" : 8, "name" : "li_8", "age" : 18 }
{ "_id" : 9, "name" : "li_9", "age" : 18 }
{ "_id" : 11, "age" : 22, "likes" : [ "ling", "li" ], "name" : "li_11" }
> db.users.find({likes:/ling/});
{ "_id" : 11, "age" : 22, "likes" : [ "ling", "li" ], "name" : "li_11" }
>
> db.users.find({likes:{$size:2}});
注意:在mongoDB中使用正则表达式可以是实现近似模糊查询功能
排序
db.集合名称.find ( ).sort({name : 1,age:1}).-1升序-1降序
类似 SQL语甸为: 'order by name , age ’
分页
db.集合名称.find() . sort({条件}).skip(start) .limit(rows) ;
类似于SQL语句为:“limit start , rows”
总条数
db.集合名称.count():
db.集合名称.find( {"name":"li"}).count();
类似于SQL语句为:“select count(id) from …”
去重
db.集合名称.distinet("字段")
指定返回字段
> db.集合名称.find({条件},{name:1,age :1})
$type
描述
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
MongoDB 中可以使用的类型如下表所示:
类型 | 数字 | 备注 |
---|
Double | 1 | | String | 2 | | Object | 3 | | Array | 4 | | Binary data | 5 | | Undefined | 6 | 已废弃。 | Object id | 7 | | Boolean | 8 | | Date | 9 | | Null | 10 | | Regular Expression | 11 | | JavaScript | 13 | | Symbol | 14 | | JavaScript (with scope) | 15 | | 32-bit integer | 16 | | Timestamp | 17 | | 64-bit integer | 18 | | Min key | 255 | Query with -1 . | Max key | 127 | |
>db.col.insert({
title: 'PHP 教程',
description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。',
by: 'li',
url: 'http://www.runoob.com',
tags: ['php'],
likes: 200
})
>db.col.insert({title: 'Java 教程',
description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。',
by: 'li',
url: 'http://www.runoob.com',
tags: ['java'],
likes: 150
})
>db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: 'li',
url: 'http://www.runoob.com',
tags: ['mongodb'],
likes: 100
})
如果想获取 “col” 集合中 title 为 String 的数据,你可以使用以下命令:
db.col.find({"title" : {$type : 2}})
或
db.col.find({"title" : {$type : 'string'}})
索引
官方文档地址: Indexes — MongoDB Manual
说明
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。
原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6pCqZJA-1652786798078)(MongoDB.assets/1652607800935.png)]
从根本上说,MongoDB中的索引与其他数据库系统中的索引类似。MongoDB在集合层面上定义了索引,并支持对MongoDB集合中的任何字段或文档的子字段进行索引。
操作
创建索引:
MongoDB使用 createIndex() 方法来创建索引。
注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名
> db.集合名称.createIndex(keys, options)
> db.集合名称.createIndex({"title":1,"description":-1})
语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
createIndex() 接收可选参数,可选参数列表如下:
Parameter | Type | Description |
---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。 | unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. | name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 | dropDups | Boolean | **3.0+版本已废弃。**在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. | sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. | expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 | v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 | weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 | default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 | language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
1、查看集合索引
db.集合名称.getIndexes()
2、查看集合索引大小
db.集合名称.totalIndexSize()
3、删除集合所有索引
db.集合名称.dropIndexes()
4、删除集合指定索引
db.集合名称.dropIndex("索引名称")
利用 TTL 集合对存储的数据进行失效时间设置:经过指定的时间段后或在指定的时间点过期,MongoDB 独立线程去清除数据。类似于设置定时自动删除任务,可以清除历史记录或日志等前提条件,设置 Index 的关键字段为日期类型 new Date()。
例如数据记录中 createDate 为日期类型时:
- 设置时间180秒后自动清除。
- 设置在创建记录后,180 秒左右删除。
db.集合名称.createIndex({"createDate": 1},{expireAfterSeconds: 180})
由记录中设定日期点清除。
设置 A 记录在 2019 年 1 月 22 日晚上 11 点左右删除,A 记录中需添加 “ClearUpDate”: new Date(‘Jan 22, 2019 23:00:00’),且 Index中expireAfterSeconds 设值为 0。
db.集合名称.createIndex({"ClearUpDate": 1},{expireAfterSeconds: 0})
其他注意事项:
- 索引关键字段必须是 Date 类型。
- 非立即执行:扫描 Document 过期数据并删除是独立线程执行,默认 60s 扫描一次,删除也不一定是立即删除成功。
- 单字段索引,混合索引不支持。
复合索引
说明:一个索引的值是由多个key进行维护的索引的称之为复合索引
> db.集合名称.createIndex({"title":1,"description":-1})
聚合
说明:
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
有点类似 SQL 语句中的 count(*)。
注意: mongoDB中复合索引和传统关系型数据库一致都是左前缀原则
{
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
},
现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:
> db.集合名称.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
"result" : [
{
"_id" : "runoob.com",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
>
以上实例类似sql语句:
select by_user, count(*) from mycol group by by_user
在上面的例子中,我们通过字段 by_user 字段对数据进行分组,并计算 by_user 字段相同值的总和。
下表展示了一些聚合的表达式:
表达式 | 描述 | 实例 |
---|
$sum | 计算总和。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
s
u
m
:
"
sum : "
sum:"likes"}}}]) | $avg | 计算平均值 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
a
v
g
:
"
avg : "
avg:"likes"}}}]) | $min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
m
i
n
:
"
min : "
min:"likes"}}}]) | $max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
m
a
x
:
"
max : "
max:"likes"}}}]) | $push | 将值加入一个数组中,不会判断是否有重复的值。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {
p
u
s
h
:
"
push: "
push:"url"}}}]) | $addToSet | 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {
a
d
d
T
o
S
e
t
:
"
addToSet : "
addToSet:"url"}}}]) | $first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", first_url : {
f
i
r
s
t
:
"
first : "
first:"url"}}}]) | $last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", last_url : {
l
a
s
t
:
"
last : "
last:"url"}}}]) |
./mongod
整合应用
说明:这里主要以springboot应用为基础应用进行整合开发
环境搭建
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
编写配置
# 无密码时 mongodb(协议)://192.168.49.128(ip地址):27017(端口)/users(库名)
spring.data.mongodb.uri=mongodb://192.168.49.128:27017/users
# 有密码时
spring.data.mongodb.host=192.168.49.128
spring.data.mongodb.database=users
spring.data.mongodb.username=root
spring.data.mongodb.password=root
spring.data.mongodb.port=27017
操作集合
? 注意:创建集合不能存在,存在报错
@Test
public void testDropCollection(){
mongoTemplate.dropCollection("products");
}
相关注解
-
@Document
-
@Id
- 修饰范围:用在成员变量、方法上
- 作用:用来将成员变量的值映射为文档的_id的值
-
@Field
- 修饰范围:用在成员变量、方法上。
- 作用:用来将成员变量以及值映射为文档中一个key、value对
- 属性:( name , value )用来指定在文档中 key的名称,默认为成员变量名
-
@Transient
- 修饰范围:用在成员变量、方法上。
- 作用:用来指定改成员变量,不参与文档的序列化
文档操作
-
查询
-
Criteria -
Criteria | MongoDB | 说明 |
---|
Criteria and(String key) | $and | 并且 | Criteria andOperator(Criteria …criteria) | $and | 并且 | Criteria orOperator(Criteria …criteria) | $or | 或者 | Criteria gt(Object o) | $gt | 大于 | Criteria gte(Object o) | $gte | 大于等于 | Criteria in(Object… o) | $in | 包含 | Criteria is(Object o) | $is | 等于 | Criteria it(Object o) | $it | 小于 | Criteria ite(Object o) | $ite | 小于等于 | Criteria nin(Object… o) | $nin | 不包含 |
-
常见查询
@Test
public void testFind() {
Query query = new Query();
query.with(Sort.by(
Sort.Order.desc("salary"))).skip(1).limit(2);
List<Users> users = mongoTemplate.find(query, Users.class);
users.forEach(System.out::println);
long count = mongoTemplate.count(new Query(), Users.class);
System.out.println(count);
List<String> name = mongoTemplate.findDistinct(new Query(), "name", Users.class, String.class);
name.forEach(System.out::println);
Query bson = new BasicQuery("{name:'li'}");
List<Users> users1 = mongoTemplate.find(query, Users.class);
users1.forEach(System.out::println);
}
@Test
public void test() {
Users li = new Users(2, "ling", 200d, new Date());
mongoTemplate.insert(li);
}
o insert:插入重复数据时: insert报 DuplicateKeyException`提际主键重复;save对已存在的数据进行更新。 o save:批处理操作时:insert可以一次性插入整个数据,效率较高;save需遍历整个数据。一次插入或更新。效率较低。
@Test
public void testUpdate() {
Update update = new Update();
update.set("salary", 4000);
mongoTemplate.updateFirst(Query.query(Criteria.where("name").is("li")), update, Users.class);
mongoTemplate.updateMulti(Query.query(Criteria.where("name").is("li")), update, Users.class);
update.setOnInsert("id", 10);
UpdateResult updateResult = mongoTemplate.upsert(Query.query(Criteria.where("name").is("li")), update, Users.class);
updateResult.getModifiedCount();
updateResult.getMatchedCount();
updateResult.getUpsertedId();
}
@Test
public void testDelete() {
mongoTemplate.remove(new Query(),Users.class);
mongoTemplate.remove(Query.query(Criteria.where("name").is("li")),Users.class);
}
副本集
官网地址: Replication — MongoDB Manual
说明:
MongoDB副本集(Replica Set)是有自动故障恢复功能的主从集群,有一个Primary节点和一个或多个Secondary节点组成。副本集没有固定的主节点,当主节点发生故障时整个集群会选举一个主节点为系统提供服务以保证系统的高可用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1JyaxVgI-1652786798079)(MongoDB.assets/1652669576881.png)]
以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。
Automatic Failover
自动故障转移机制:当主节点未与集合的其他成员通信超过配置的选举超时时间〈默认为10秒)时,合格的辅助节点将调用选举以将自己提名为新的主节点。集群尝试完成新主节点的选举并恢复正常操作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p8QFPAWR-1652786798080)(MongoDB.assets/1652670305749.png)]
搭建副本集
$ ./mongod --port 27017 --dbpath ../repl/data1 --bind_ip 0.0.0.0 --replSet myreplace/[192.168.49.128:27818,192.168.49.128:27819]
$ ./mongod --port 27018 --dbpath ../repl/data2 --bind_ip 0.0.0.0 --replSet myreplace/[192.168.49.128:27019,192.168.49.128:27817]
$ ./mongod --port 27019 --dbpath ../repl/data3 --bind_ip 0.0.0.0 --replSet myreplace/[192.168.49.128:27017,192.168.49.128:27818]
注意:–replSet副本集myreplace副本集名称/集群中其他节点的主机和端口
-
配置副本集,连接任意节点
-
use admin -
初始化副本集 > var config = {
_id : " myreplace",
members : [
{_id:0,host:"192.168.49.128:27017"},
{_id:1,host:"192.168.49.128:27018"},
{_id:2,host:"192.168.49.128 :27019"}]
}
> rs.initiate(corfig);
> rs.slaveOk();
分片集群
官网地址: Sharding — MongoDB Manual
说明
分片(sharding)是指将数据拆分,将其分散存在不同机器的过程,有时也用==分区 (partitioning)==来表示这个棍念,将数据分散在不同的机器上,不需要功能强大的大型计算机就能存储更多的数据,处理更大的负载。 分片目的是通过分片能够增加更多机器来应对不断的增加负载和数据,还不影响应用运行。 MongoDB支持自动分片,可以摆脱手动分片的管理困扰,集群自动切分数据做负载均衡。MongoDB分片的基本思想就是将集合拆分成多个块,这些快分散在若干个片里,每个片只负责总数据的一部分,应用程序不必知道哪些片对应哪些数据,甚至不需要知道数据拆分了,所以在分片之前会运行一个路由进程,mongos进程,这个路由器知道所有的数据存放位置,应用只需要直接与mongos交互即可。mongos自动将请求转到相应的片上获取数据,从应用角度看分不分片没有什么区别。
架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-njRllfy0-1652786798080)(MongoDB.assets/1652677472082.png)]
上图中主要有如下所述三个主要组件:
-
Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障 -
Config Server: mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。 -
Query Routers: 前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。 -
Shard Key: 片键,设置分片时需要在集合中选一个键,用该键的值作为拆分数据的依据,这个片键称之为(shard key),片键的选取很重要,片键的选取决定了数据散列是否均匀。
搭建
#1.集群规划
- Shard server 1: 27017
- Shard Repl 1: 27018
- Shard Server 2: 27019
- Shard Repl 2: 27028
- Shard Server 3: 27821
- shard Repl 3: 27822
- Config Server : 27823
- Config Server : 27024
- Config Server : 27825
- Route Process : 27026
# 2.进入安装的 bin 目录创建数据目录
- mkdir -p ../cluster/shard/s0
- mkdir -p ../cluster/shard/s0-repl
- mkdir -p ../cluster/shard/s1
- mkdir -p ../cluster/shard/s1-repl
- mkdir -p ../cluster/shard/s2
- mkdir -p ../cluster/shard/s2-repl
- mkdir -p ..lcluster/shard/config1
- mkdir -p ../cluster/shard/config2
- mkdir -p ../cluster/shard/config3
# 3.启动4个shard服务
# 启动 s0、r0
> ./mongod --port 27017 --dbpath ../cluster/shard/s0 --bind_ip 0.0.0.0 --shardsvr --replSet r0/192.168.49.128:27818
> ./mongod --port 27018 --dbpath ../cluster/shard/s0-repl --bind_ip 0.0.0.0 --shardsvr --replSet r0/192.168.49.128:27817
-- 1.登录任意节点
-- 2. use admin
-- 3.执行
config = {_id : "r0" , members: [
{_id :0, host : "192.168.49.128:27817"},
{_id :1, host : "192.168.49.128:27818"},]
}
rs.initiate(config);//初始化
# 启动s1、r1
> ./mongod --port 27019 --dbpath ../cluster/shard/s1 --bind_ip 0.0.0.0 --shardsvr --replSet r1/192.168.49.128:27028
> ./mongod --port 270120 --dbpath ../cluster/shard/s1-repl --bind_ip 0.0.0.0 --shardsvr --replSet r1/192.168.49.128:27019
-- 1.登录任意节点
-- 2. use admin
-- 3.执行
config = {_id : " r1", members: [
{_id :0, host : "192.168.49.128:27019"},
{_id :1, host : "192.168.49.128:27020"},]
}
# 启动s2、r2
>./mongod --port 27021 --dbpath ../cluster/shard/s2 --bind_ip 0.0.0.0 --shardsvr --replset r2/192.168.49.128:27822
> ./mongod --port 27822--dbpath ../cluster/shard/s2-repl --bind_ip 0.0.0.0--shardsvr --replSet r2/192.168.49.128:27021
--1.登录任意节点
-- 2. use admin
-- 3.执行
config = { _id :" r2" ,members : [
{_id :0, host : "192.168.49.128:27021"},
{_id :1 , host : "192.168.49.128:27022"},]
}
re initiate( confing); // 初始化
# 4.启动3个config服务
> ./mongod --port 27023 --dbpath ../cluster/shard/config1 --bind_ip 0.0.0.0 --replSet config/[192.168.49.128:27024,192.168.49.128:27025] --configsvr
> ./mongod --port 27824 --dbpath ../cluster/shard/config2 --bind_ip 0.0.0.0 --replSet config/[192.168.49.128:27823,192.168.49.128:27025] --configsvr
> ./mongod --port 27025--dbpath ../cluster/shard/config3 --bind_ip 0.0.0.0 --replSet config/[192.168.49.128:27023,192.168.49.128:27024] --configsvr
# 5.初始化config server副本集
# 登录任意节点congfig server
> 1.use admin
>2.在admin中执行
var config = {
_id : "config" ,
configsvr: true,
members :[
{_id : 0 , host : "192.168.49.128:27023"},
{_id : 1 , host: "192.168.49.128:27824"},
{_id : 2, host : "192.168.49.128:27025"}]
}
> 3.rs.initiate(config); // 初始化副本集配置
# 6.启动mongos 路由服务
> ./mongos --port 27826 --configdb config/192.168.49.128:27023,192.168.49.128:27024,192.168.49.128:27025 --bind_ip 0.0.0.0
# 7.登录mongos服务
>1.登录 mongo --port 27026
> 2.use admin
> 3.添加分片信息
db.runCommand({ addshard:"r0/192.168.49.128:27017,192.168.49.128:27018","allowLocal":true});
db.runCommand({ addshard:"r1/192.168.49.128:27019,192.168.49.128:27020","allowLocal":true});
db.runCommand({ addshard:"r2/192.168.49.128:27021,192.168.49.128:27022","allowLocal":true});
>4.指定分片的数据库
db.runCommand({enablesharding:"li"});
>5.设置库的片键信息
db.runCommand({ shardcollection:"li.users", key:{ _id:1}})
db.runCommand({ shardcollection:"li.users", key:{ _id: "hashed"}})
1. 创建Sharding复制集 rs0
1.1 复制集rs0配置
# mongo localhost:27020 > rs.initiate({_id: ‘rs0’, members: [{_id: 0, host: ‘localhost:27020’}, {_id: 1, host: ‘localhost:27021’}]}) > rs.isMaster() #查看主从关系
2. 创建Sharding复制集 rs1
2.1 复制集rs1配置
> rs.initiate({_id: 'rs1', members: [{_id: 0, host: 'localhost:27030'}, {_id: 1, host: 'localhost:27031'}]})
> rs.isMaster()
3. 创建Config复制集 conf
3.1 复制集conf配置
> rs.initiate({_id: 'conf', members: [{_id: 0, host: 'localhost:27100'}, {_id: 1, host: 'localhost:27101'}]})
> rs.isMaster()
4. 创建Route
4.1 设置分片
> use admin
> db.runCommand({ addshard: 'rs0/localhost:27020,localhost:27021'})
> db.runCommand({ addshard: 'rs1/localhost:27030,localhost:27031'})
> db.runCommand({ enablesharding: 'test'})
> db.runCommand({ shardcollection: 'test.user', key: {name: 1}})
|