
MongoDB 教程
什么是MongoDB
MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB特点
它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:
- 面向集合存储,易存储对象类型的数据。
- 模式自由。
- 支持动态查询。
- 支持完全索引,包含内部对象。
- 支持查询。
- 支持复制和故障恢复。
- 使用高效的二进制数据存储,包括大型对象(如视频等)。
- 自动处理碎片,以支持云计算层次的扩展性
- 支持Ruby,python,Java,C++,PHP,C#等多种语言。
- 文件存储格式为BSON(一种JSON的扩展)。
- 可通过网络访问。
MongoDB适用场景
MongoDB 的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)和传统的RDBMS 系统(具有丰富的功能)之间架起一座桥梁,它集两者的优势于一身。
Mongo 适用于以下场景:
● 网站数据:Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
● 缓存:由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo 搭建的持久化缓存层可以避免下层的数据源过载。
● 大尺寸、低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
● 高伸缩性的场景:Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持。
● 用于对象及JSON 数据的存储:Mongo 的BSON 数据格式非常适合文档化格式的存储及查询。
MongoDB 的使用也会有一些限制,例如,它不适合于以下几个地方。
● 高度事务性的系统:例如,银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
● 传统的商业智能应用:针对特定问题的BI 数据库会产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
● 需要SQL 的问题。
Mongo不适用的场景如下:
- 要求高度事务性的系统。
- 传统的商业智能应用。
- 复杂的跨文档(表)级联查询。
mongodb使用
查看数据库
| show dbs |
| |
| > show dbs |
| local 0.078GB |
| test 0.078GB |
| > |
创建数据库
| > use youj |
| switched to db youj |
| > db |
删除数据库
删除数据库要先进入数据库才能删除数据库
| > use youdb1 |
| switched to db youdb1 |
| > db.dropDatabase() |
| { "dropped" : "youdb1", "ok" : 1 } |
查看集合
如果要查看已有集合,可以使用 show collections 或 show tables 命令
| > show collections |
| runoob |
| system.indexes |
创建集合
| db.createCollection(name, options) |
参数说明:
- name: 要创建的集合名称
- options: 可选参数, 指定有关内存大小及索引的选项
options 可以是如下参数:
字段 |
类型 |
描述 |
capped |
布尔 |
(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。 |
autoIndexId |
布尔 |
3.2 之后不再支持该参数。(可选)如为 true,自动在 _id 字段创建索引。默认为 false。 |
size |
数值 |
(可选)为固定集合指定一个最大值,即字节数。 如果 capped 为 true,也需要指定该字段。 |
max |
数值 |
(可选)指定固定集合中包含文档的最大数量。 |
| > use test |
| switched to db test |
| > db.createCollection("runoob") |
| { "ok" : 1 } |
| > |
删除集合
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
| >use mydb |
| switched to db mydb |
| >show collections |
| mycol |
| mycol2 |
| system.indexes |
| runoob |
| >db.mycol2.drop() |
| true |
| > |
| |
插入文档
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 异常,提示主键重复,不保存当前数据。
| >db.col.insert({title: 'MongoDB 教程', |
| description: 'MongoDB 是一个 Nosql 数据库', |
| by: 'w3cschool', |
| url: 'http://www.w3cschool.cn', |
| tags: ['mongodb', 'database', 'NoSQL'], |
| likes: 100 |
| }) |
insertOne
db.collection.insertOne() 用于向集合插入一个新文档
| db.collection.insertOne( |
| <document>, |
| { |
| writeConcern: <document> |
| } |
| ) |
insertMany
| db.collection.insertMany( |
| [ <document 1> , <document 2>, ... ], |
| { |
| writeConcern: <document>, |
| ordered: <boolean> |
| } |
| ) |
- document:要写入的文档。
- writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
- ordered:指定是否按顺序写入,默认 true,按顺序写入。
更新文档
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的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
| db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}}) |
查询文档
MongoDB 查询文档使用 find() 方法。
| db.collection.find(query, projection) |
- query :可选,使用查询操作符指定查询条件
- projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
操作 |
格式 |
范例 |
RDBMS中的类似语句 |
等于 |
{<key>:<value> } |
db.col.find({"by":"菜鸟教程"}).pretty() |
where by = '菜鸟教程' |
小于 |
{<key>:{$lt:<value>}} |
db.col.find({"likes":{$lt:50}}).pretty() |
where likes < 50 |
小于或等于 |
{<key>:{$lte:<value>}} |
db.col.find({"likes":{$lte:50}}).pretty() |
where likes <= 50 |
大于 |
{<key>:{$gt:<value>}} |
db.col.find({"likes":{$gt:50}}).pretty() |
where likes > 50 |
大于或等于 |
{<key>:{$gte:<value>}} |
db.col.find({"likes":{$gte:50}}).pretty() |
where likes >= 50 |
不等于 |
{<key>:{$ne:<value>}} |
db.col.find({"likes":{$ne:50}}).pretty() |
where likes != 50 |
pretty
以易读的方式来读取数据
and条件
| db.col.find({key1:value1, key2:value2}).pretty() |
or条件
| db.col.find( |
| { |
| $or: [ |
| {key1: value1}, {key2:value2} |
| ] |
| } |
| ).pretty() |
| db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty() |
and or 联合使用
| >db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty() |
| |
| likes > 50 and (title == MongoDB 教程 or by == 菜鸟教程) |
| { |
| "_id" : ObjectId("56063f17ade2f21f36b03133"), |
| "title" : "MongoDB 教程", |
| "description" : "MongoDB 是一个 Nosql 数据库", |
| "by" : "菜鸟教程", |
| "url" : "http://www.runoob.com", |
| "tags" : [ |
| "mongodb", |
| "database", |
| "NoSQL" |
| ], |
| "likes" : 100 |
| } |
$type 操作符
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果
类型 |
数字 |
备注 |
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 |
|
如果想获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令
| db.col.find({"title" : {$type : 2}}) |
| db.col.find({"title" : {$type : 'string'}}) |
Limit
读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
| db.COLLECTION_NAME.find().limit(NUMBER) |
| db.col.find({},{"title":1,_id:0}).limit(2) |
| { "title" : "PHP 教程" } |
| { "title" : "Java 教程" } |
| > |
Skip
使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
| db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER) |
读取第2条数据
| >db.col.find({},{"title":1,_id:0}).limit(1).skip(1) |
| { "title" : "Java 教程" } |
| > |
排序
使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
| db.COLLECTION_NAME.find().sort({KEY:1}) |
col 集合中的数据按字段 likes 的降序排列
| >db.col.find({},{"title":1,_id:0}).sort({"likes":-1}) |
| { "title" : "PHP 教程" } |
| { "title" : "Java 教程" } |
| { "title" : "MongoDB 教程" } |
| > |
聚合
MongoDB中聚合的方法使用aggregate()。
| >db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION) |
| { |
| _id: ObjectId(7df78ad8902c) |
| title: 'MongoDB Overview', |
| description: 'MongoDB is no sql database', |
| by_user: 'runoob.com', |
| url: 'http://www.runoob.com', |
| tags: ['mongodb', 'database', 'NoSQL'], |
| likes: 100 |
| }, |
| { |
| _id: ObjectId(7df78ad8902d) |
| 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 |
| }, |
| { |
| _id: ObjectId(7df78ad8902e) |
| 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.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) |
| { |
| "result" : [ |
| { |
| "_id" : "runoob.com", |
| "num_tutorial" : 2 |
| }, |
| { |
| "_id" : "Neo4j", |
| "num_tutorial" : 1 |
| } |
| ], |
| "ok" : 1 |
| } |
| > |
聚合的表达式:
$sum |
计算总和。 |
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg |
计算平均值 |
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min |
获取集合中所有文档对应值得最小值。 |
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max |
获取集合中所有文档对应值得最大值。 |
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push |
将值加入一个数组中,不会判断是否有重复的值。 |
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet |
将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。 |
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first |
根据资源文档的排序获取第一个文档数据。 |
db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last |
根据资源文档的排序获取最后一个文档数据 |
db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
删除文档
MongoDB remove() 函数是用来移除集合中的数据。
| db.collection.remove( |
| <query>, |
| { |
| justOne: <boolean>, |
| writeConcern: <document> |
| } |
| ) |
| db.col.remove({'title':'MongoDB 教程'}) |
如果你只想删除第一条找到的记录可以设置 justOne 为 1
| db.COLLECTION_NAME.remove(DELETION_CRITERIA,1) |
删除文档全部数据
索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
createIndex
| db.collection.createIndex(keys, options) |
Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
| >db.col.createIndex({"title":1,"description":-1}) |
| > |
| |
参数介绍:
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. |
在后台创建索引:
| db.values.createIndex({open: 1, close: 1}, {background: true}) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能