MongoDB 入门
MongoDB 入门
MongoDB是一个以文档为中心的NOSQL数据库,具备高性能、高可用性及可伸缩性等特性。
下面介绍MongoDB中的基础概念:
Database/数据库
与关系数据库类似,MongoDB中,数据库代表了一个独立的数据存储库,每个数据库在文件系统上都有自己的一组文件。一个MongoDB服务器通常有多个数据库。
Collection/集合
Collection/集合是一组MongoDB文档,相当于关系数据库中的表,包含于数据库中。与关系数据库的表不同,集合不要求固定一致的表结构,集合中的文档可以有不同的字段。但是,集合中的文档都应具有相似或相关联的意义,例如:订单集合,包含了全部订单文档。
Document/文档
文档是一组JSON格式的键值对,。文档具有动态数据结构,同一集合中的文档不需要具有相同的字段集。
下表显示了RDBMS术语与MongoDB之间的关系。
| 关系数据库 | MongoDB |
|---|---|
| Database | Database |
| Table | Collection |
| Tuple/Row | Document |
| column | Field |
| Table Join | Embedded Documents |
| Primary Key | Primary Key (由mongodb本身提供的默认键_id) |
| 服务器和客户端 | |
| Mysqld/Oracle | mongod |
| mysql client | mongo |
文档示例
下面的示例,显示了一个站点的文档结构,是一组逗号分隔的键值对。
{
_id: ObjectId("507f191e810c19729de860ea")
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by: 'demo',
url: 'httpS://www.baidu.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100,
comments: [
{
user:'user1',
message: 'My first demo',
dateCreated: new Date(2021,7,30,15,15),
like: 0
},
{
user:'user2',
message: 'My second demo',
dateCreated: new Date(2021,7,30,17,45),
like: 5
}
]
}
_id是一个12字节的十六进制数字,唯一标识文档。你可以在插入文档时指定_id,如果不指定,MongoDB将会生成一个。这12个字节由下面几部分组成:
- 4 字节 – 表示自Unix纪元以来的秒数
- 5 字节 – 随机值
- 3 字节 – 计数器,从一个随机值开始
MongoDB 优势
任何关系数据库都有一个典型的数据结构设计,表明了表结构及表之间的关系。而在MongoDB中,没有关系的概念。
MongoDB相对于RDBMS的优势
- 无固定结构 – MongoDB是一个文档数据库,一个集合中可以包含不同的文档。文档的字段数、内容和大小都可以不同。
- 单个对象的结构是清晰的。
- 没有复杂的表连接。
- 查询功能强大。MongoDB的查询功能几乎与SQL一样强大,使用基于文档的查询语言,可以对文档进行动态查询。
- 易于调优。
- 易于扩展。
- 应用程序对象与数据库对象天然对应。
- 使用内存存储工作集,可以更快地访问数据。
为什么使用MongoDB?
- 面向文档的数据库 – 数据以JSON格式的文档存储。
- 任意字段的索引
- 复制和高可用性
- 自动分片
- 丰富的查询
- 就地更新快
- MongoDB的专业支持
哪些场景使用MongoDB?
- 大数据
- 内容管理和交付
- 移动应用/社交应用
- 用户数据管理
- 数据中心
MongoDB 创建数据库
use 命令
MongoDB通过命令use 数据库名创建数据库。如果数据库不存在,该命令将创建一个数据库,否则将返回已有数据库。
语法
use 数据库名语句的基本语法如下:
use 数据库名
例子
如果想使用名为test的数据库,可通过如下命令
> use test
switched to db test
要检查当前数据库,可使用db命令:
> db
test
如果要列出全部数据库,可使用show dbs命令:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
您刚创建的数据库(mydb)不在列表中,空数据库不会显示,需要向其插入至少一个文档。
> db.site.insert({"name":"demo"})
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
MongoDB 删除数据库
dropDatabase() 方法
MongoDB db.dropDatabase() 命令用于删除数据库。
语法
dropDatabase()命令的基本语法如下:
db.dropDatabase()
这将删除当前数据库。如果没有选择任何数据库,那么它将删除默认的“test”数据库。
例子
首先,使用命令show dbs检查可用数据库列表。
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
如果想删除数据库test,可通过如下操作:
> use testswitched to db test> db.dropDatabase(){ "dropped" : "test", "ok" : 1 }
现在检查数据库列表。
> show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GB
MongoDB 创建集合
createCollection() 方法
MongoDB中的db.createCollection(name, options)方法用于创建集合。
语法
createCollection()命令的基本语法如下:
db.createCollection(name, options)
命令中,name是要创建的集合名称,options是一个文档,用于指定集合的配置。
| 参数 | 类型 | 描述 |
|---|---|---|
| Name | String | 要创建的集合名称 |
| Options | Document | (可选)指定内存大小、索引等选项/td> |
options参数是可选的,下面是可以使用的选项列表:
| 字段 | 类型 | 描述 |
|---|---|---|
| capped | Boolean | (可选)如果为真,则启用有上限的集合。封顶集合是一个固定大小的集合,当它达到最大大小时自动覆盖其最老的条目。 如果指定为真,还需要指定size参数。 |
| size | number | (可选)为有上限的集合指定最大字节大小。如果capped为真,那么还需要指定该字段。 |
| max | number | (可选)指定上限集合中允许的最大文档数量。 |
在插入文档时,MongoDB首先检查封顶集合的size字段,然后检查max字段。
例子
没有选项的createCollection()方法例子如下:
> use testswitched to db test> db.createCollection("mycollection"){ "ok" : 1 }
可以使用show collections命令检查当前数据库中的集合。
> show collectionsmycollectiontest
下面是createCollection()方法使用选项的例子
> db.createCollection("mycollection3", { capped : true, size : 6142800, max : 10000 } ){ "ok" : 1 }
MongoDB中,不需要创建集合,当插入文档时,MongoDB自动创建集合。
> db.test1.insert({"post": "mongodb"})WriteResult({ "nInserted" : 1 })> show collectionsmycollectionmycollection1testtest1
MongoDB 删除集合
drop() 方法
drop() 方法用于从数据库中删除集合。
语法
drop()命令的基本语法如下
db.COLLECTION_NAME.drop()
例子
首先显示数据库test中的所有集合。
> use testswitched to db test> show collectionsmycollectionmycollection1testtest1
现在删除名为mycollection2的集合。
> db.mycollection1.drop()true
再次将集合列表检查到数据库中。
> show collectionsmycollectiontesttest1
如果集合被成功删除,drop()方法将返回true,否则返回false。
MongoDB 数据类型
MongoDB支持许多数据类型。常用的一些是
- String − 字符串是最常用的数据类型,MongoDB中的字符串必须是UTF-8编码。
- Integer − 整数类型用于存储数值。整数可以是32位,也可以是64位,这取决于你的服务器。
- Boolean − 布尔类型用于存储布尔值(true/ false)。
- Double − 双精度类型用于存储浮点值。
- Min/ Max keys − 此类型用于将值与最低和最高的BSON元素进行比较。
- Arrays − 此类型用于将数组、列表或多个值存储到一个键中。
- Timestamp − ctimestamp。时间戳,用于记录文档何时被修改或创建。
- Object − 这种数据类型用于嵌入文档。
- Null − 此类型用于存储Null值。
- Symbol − 此数据类型与字符串用法相同; 然而,它通常用于某些使用特定符号的语言。
- Date − 此数据类型用于以UNIX时间格式存储当前日期或时间。您可以通过创建date对象,并将日、月、年传入其中,来指定自己的日期时间。
- Object ID − 此数据类型用于存储文档的ID。
- Binary data − 这种数据类型用于存储二进制数据。
- Code − 此数据类型用于将JavaScript代码存储到文档中。
- Regular expression − 此数据类型用于存储正则表达式。
MongoDB 插入文档
insert() 方法
要将数据插入MongoDB集合,需要使用insert()或save()方法。
语法
insert()命令的基本语法如下
>db.COLLECTION_NAME.insert(document)
例子
>db.test1.insert({ title: 'MongoDB 入门', description: 'MongoDB是开源的NoSQL数据库', by: 'test', url: 'https://www.baidu.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100})
这里test1是我们的集合名称,在前面创建过。如果集合不存在,那么MongoDB将创建这个集合,然后将文档插入其中。
在插入的文档中,如果没有指定_id参数,则MongoDB为该文档分配一个唯一的ObjectId。
_id是一个集合中,每个文档唯一标识,_id是12个字节的16进制数字。12字节划分如下
- 4 字节 – 表示自Unix纪元以来的秒数
- 5 字节 – 随机值
- 3 字节 – 计数器,从一个随机值开始
要在一次查询中插入多个文档,可以在insert()命令中,传递一个文档数组。
例子
> db.test1.insert([ { title: 'MongoDB 入门', description: 'MongoDB是一个以文档为中心的NOSQL数据库', by: 'test', url: 'https://www.baidu.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 88 }, { title: 'MongoDB 优势', description: "MongoDB相对于RDBMS的优势", by: 'test', url: 'https://www.baidu.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 89, comments: [ { user:'user1', message: 'My first comment', dateCreated: new Date(2021,6,31,2,35), like: 0 } ] }])
要插入文档,还可以使用db.post.save(document)方法。如果没指定_id,那么save()方法将与insert()方法一样,自动生成_id。如果指定_id,则它将替换_id所标识文档的整个数据。
MongoDB 查询文档
find() 方法
要从MongoDB集合查询数据,需要使用find()方法。
语法
find()方法的基本语法如下
db.COLLECTION_NAME.find()
方法显示文档时,是没有结构化的。
pretty() 方法
要以格式化的方式显示结果,可以使用pretty()方法。
语法
db.mycollection.find().pretty()
例子
> db.test1.find().pretty(){ "_id" : ObjectId("6103b4425c56b69ebcf036c7"), "title" : "MongoDB 概述", "description" : "MongoDB是一个以文档为中心的NOSQL数据库", "by" : "test", "url" : "https://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 88}
除了find()方法之外,还有findOne()方法,它只返回一个结果。
> db.test1.findOne(){ "_id" : ObjectId("6103b4425c56b69ebcf036c7"), "title" : "MongoDB 概述", "description" : "MongoDB是一个以文档为中心的NOSQL数据库", "by" : "test", "url" : "https://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 88}
MongoDB查询条件与SQL Where对比
find()方法可以传入查询条件,为便于理解,下表列出了等价的SQL Where语句。
| 操作 | 语法 | 例子 | 等价于 |
|---|---|---|---|
| 等于 | { |
db.mycol.find({“by”:”qikegu.com”}).pretty() | where by = ‘qikegu.com’ |
| 小于 | { |
where likes < 50 | |
| 小于等于 | { |
where likes <= 50 | |
| 大于 | { |
where likes > 50 | |
| 大于等于 | { |
where likes >= 50 | |
| 不等于 | { |
where likes != 50 |
AND
语法
在find()方法中,查询条件可以使用AND,下面是AND的基本语法
> db.test1.find( { $and: [ {key1: value1}, {key2:value2} ] }).pretty()
$and也可以省略,直接传入键值对,以逗号分隔,格式如下:
> db.test.find( { key1: value1, key2:value2 }).pretty()
例子
下面的例子将显示由’test’编写并且标题是’MongoDB 概述’的所有教程’。
> db.test1.find({$and:[{"by": "test"},{"title": "MongoDB 概述"}]}).pretty() { "_id" : ObjectId("6103b4425c56b69ebcf036c7"), "title" : "MongoDB 概述", "description" : "MongoDB是一个以文档为中心的NOSQL数据库", "by" : "test", "url" : "https://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 88 }
对于上面的示例,等效where子句是where by = 'test'和' title = 'MongoDB 概述'。可以在find子句中传递任意数量的键值对。
OR
语法
在find()方法中,查询条件可以使用OR,下面是OR的基本语法
> db.test1.find( { $or: [ {key1: value1}, {key2:value2} ] }).pretty()
例子
下面的例子将显示由“test”编写或标题为“MongoDB 概述”的教程。
> db.test1.find({$or:[{"by": "test"},{"title": "MongoDB 概述"}]}).pretty(){ "_id" : ObjectId("6103b4425c56b69ebcf036c7"), "title" : "MongoDB 概述", "description" : "MongoDB是一个以文档为中心的NOSQL数据库", "by" : "test", "url" : "https://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 88}{ "_id" : ObjectId("6103b4425c56b69ebcf036c8"), "title" : "MongoDB 优势", "description" : "MongoDB相对于RDBMS的优势", "by" : "test", "url" : "https://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 89, "comments" : [ { "user" : "user1", "message" : "My first comment", "dateCreated" : ISODate("2021-07-30T18:35:00Z"), "like" : 0 } ]}
AND, OR 一起使用
例子
下面的示例将显示符合以下条件的文档:获赞数大于88,并且要么标题是“MongoDB 概述”,要么由”test”编写。等效SQL where子句是where like >88 AND (by = 'test'或title = 'MongoDB 概述')
> db.test1.find({"likes": {$gt:88}, $or: [{"by": "test"}, {"title": "MongoDB 概述"}]}).pretty() { "_id" : ObjectId("6103b4425c56b69ebcf036c8"), "title" : "MongoDB 优势", "description" : "MongoDB相对于RDBMS的优势", "by" : "test", "url" : "https://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 89, "comments" : [ { "user" : "user1", "message" : "My first comment", "dateCreated" : ISODate("2021-07-30T18:35:00Z"), "like" : 0 } ] }
MongoDB 更新文档
MongoDB的update()和save()方法可用于更新文档。
MongoDB Update() 方法
update()方法类似SQL UDPATE语句,可以根据条件更新现有文档。
语法
update()方法的基本语法如下
db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)
例子
假设test1集合有以下数据。
{ "_id" : ObjectId("6103b3935c56b69ebcf036c3"), "title" : "MongoDB 入门", }{ "_id" : ObjectId("6103b3935c56b69ebcf036c4"), "title" : "MongoDB 优势" }
下面的示例,修改标题为“MongoDB 优势”的文档,把它的标题修改为“MongoDB 优点”。
> db.test1.update({'title':'MongoDB 优势'}, {$set:{'title':'MongoDB 优点'}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
默认情况下,MongoDB只更新一个文档。要更新多个文档,需要将参数“multi”设置为true。
> db.test1.update({'title':'MongoDB 入门'}, {$set:{'title':'MongoDB 概述'}},{multi:true})WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 5 })
MongoDB Save() 方法
save()方法根据文档参数更新现有文档或插入新文档。
语法
Save()方法的基本语法如下
db.COLLECTION_NAME.save({_id:ObjectId(), NEW_DATA})
例子
下面的示例,把新内容保存到_id为’6103b3935c56b69ebcf036c3’的文档中。
> db.test1.save( { "_id" : ObjectId("6103b3935c56b69ebcf036c3"), "title":"MongoDB 介绍", "by":"test" })WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
MongoDB 删除文档
remove() 方法
MongoDB的remove()方法用于从集合中删除文档。方法接受两个参数:
- deletion criteria / 删除条件 – 符合条件的文档将被删除。
- justOne – 如果设置为true或1,则只删除一个文档。
语法
remove()方法的基本语法如下
> db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)
例子
假设test1集合有以下数据:
{ "_id" : ObjectId("5cf7b4839ad87fde6fd23a03"), "title" : "MongoDB 介绍" }{ "_id" : ObjectId("5cf7b51d9ad87fde6fd23a04"), "title" : "MongoDB 概述" }{ "_id" : ObjectId("5cf7b91d9ad87fde6fd23a07"), "title" : "MongoDB 优势" }
下面的示例,将删除标题为“MongoDB 概述”的所有文档。
db.test1.remove({'title':'MongoDB 概述'})
只删除1条
如果有多个记录,只想删除第一个记录,可以在remove()方法中设置justOne参数。
> db.COLLECTION_NAME.remove(DELETION_CRITERIA, 1)
删除全部
如果没有指定删除条件,那么将删除集合中的全部文档。这相当于SQL的truncate命令。
db.test1.remove()
MongoDB 条件操作符
描述
条件操作符用于比较两个表达式并从mongoDB集合中获取数据。
MongoDB中条件操作符有:
- (>) 大于 - $gt
- (<) 小于 - $lt
- (>=) 大于等于 - $gte
- (<= ) 小于等于 - $lte
我们使用的数据库名称为"test" 我们的集合名称为"test1",以下为我们插入的数据。
为了方便测试,我们可以先使用以下命令清空集合 "test1" 的数据:
> db.test1.remove({})WriteResult({ "nRemoved" : 1 })
插入以下数据
>db.test1.insert({ "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ 'php'], "likes" :200})
>db.test1.insert({ title: 'Java 学习', description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。', by: 'demo', url: 'http://www.baidu.com', tags: ['java'], likes: 150})
>db.test1.insert({title: 'MongoDB 学习', description: 'MongoDB 是一个 Nosql 数据库', by: 'demo', url: 'http://www.badiu.com', tags: ['mongodb'], likes: 100})
使用find()命令查看数据:
> db.test1.find(){ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 100 }{ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }{ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB (>) 大于操作符 - $gt
如果你想获取 "test1" 集合中 "likes" 大于 100 的数据,你可以使用以下命令:
db.test1.find({likes : {$gt : 100}})
类似于SQL语句:
Select * from test1 where likes > 100;
输出结果:
> db.test1.find({likes : {$gt : 100}}){ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 200 }{ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }
MongoDB(>=)大于等于操作符 - $gte
如果你想获取"test1"集合中 "likes" 大于等于 100 的数据,你可以使用以下命令:
db.test1.find({likes : {$gte : 100}})
类似于SQL语句:
Select * from test1 where likes >=100;
输出结果:
> db.test1.find({likes : {$gte : 100}}){ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 200 }{ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }{ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB (<) 小于操作符 - $lt
如果你想获取"test1"集合中 "likes" 小于 150 的数据,你可以使用以下命令:
db.test1.find({likes : {$lt : 150}})
类似于SQL语句:
Select * from test1 where likes < 150;
输出结果:
> db.test1.find({likes : {$lt : 150}}){ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB (<=) 小于等于操作符 - $lte
如果你想获取"col"集合中 "likes" 小于等于 150 的数据,你可以使用以下命令:
db.test1.find({likes : {$lte : 150}})
类似于SQL语句:
Select * from test1 where likes <= 150;
输出结果:
> db.test1.find({likes : {$lte : 150}}){ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }{ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB 使用 (<) 和 (>) 查询 - $lt 和 $gt
如果你想获取"col"集合中 "likes" 大于100,小于 200 的数据,你可以使用以下命令:
db.test1.find({likes : {$lt :200, $gt : 100}})
类似于SQL语句:
Select * from test1 where likes>100 AND likes<200;
输出结果:
> db.test1.find({likes : {$lt :200, $gt : 100}}){ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }
MongoDB $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 |
使用find()命令查看数据:
> db.test1.find(){ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 100 }{ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }{ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB 操作符 - $type 实例
如果想获取 "test1" 集合中 title 为 String 的数据,你可以使用以下命令:
db.test1.find({"title" : {$type : 2}})或db.test1.find({"title" : {$type : 'string'}})
输出结果为:
{ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 200 }{ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }{ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB Projection
MongoDB中,投影/projection用于选择字段。例如,一个文档有5个字段,而你只需要3个字段,那么就可以使用投影/Projection选择需要的字段。
find() 方法
在MongoDB 查询文档中解释过,find()方法接受第二个可选参数,即要检索的字段列表。find()方法默认将返回文档的所有字段,通过设置projection可以选择要返回的字段。投影/projection是一组字段列表,值设置为1的字段返回,值为0的字段隐藏。
语法
find()方法中,投影/projection基本语法如下
> db.COLLECTION_NAME.find({}, {KEY:1})
例子
假设集合test1有以下数据
{ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习" }{ "_id" : ObjectId("6103ba645c56b69ebcf036ca"), "title" : "Java学习" }{ "_id" : ObjectId("6103ba645c56b69ebcf036cb"), "title" : "MongoDB学习" }
下面的示例,在查询文档时,只显示文档标题。
> db.test1.find({}, {"_id":0, "title":1}){ "title" : "PHP学习" }{ "title" : "Java 学习" }{ "title" : "MongoDB 学习" }
注意,在执行
find()方法时总是显示_id字段,如果不需要该字段,则需要将其设置为0。
MongoDB Limit与Skip方法
limit() 方法
类似SQL Limit语句,MongoDB中,使用limit()方法限制返回的结果数。
语法
limit()方法的基本语法如下
db.COLLECTION_NAME.find().limit(NUMBER)
例子
假设集合test1有以下数据。
{ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习" }{ "_id" : ObjectId("6103ba645c56b69ebcf036ca"), "title" : "Java学习" }{ "_id" : ObjectId("6103ba645c56b69ebcf036cb"), "title" : "MongoDB学习" }
下面的示例,在查询文档时只显示2个文档。
> db.test1.find({},{"title":1,_id:0}).limit(2){ "title" : "PHP学习" }{ "title" : "Java 学习" }
如果limit()方法中没有指定数量参数,将显示集合中的所有文档。
MongoDB Skip() 方法
除了limit()方法之外,还有一个方法skip()也接受number类型参数,用于跳过文档的数量。可以看出,Skip()方法的作用类似MySQL Offset语句。
语法
skip()方法的基本语法如下
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
例子
下面的示例,只显示第二个文档:
> db.test1.find({},{"title":1,_id:0}).limit(1).skip(1){ "title" : "Java 学习" }
注意,
skip()方法的默认值是0。
MongoDB 排序
sort() 方法
要在MongoDB中对结果进行排序,可使用sort()方法。该方法接受一个包含字段列表及其排序顺序的参数,要指定排序顺序,使用1和-1,1用于升序,-1用于降序。
语法
sort()方法的基本语法如下
db.COLLECTION_NAME.find().sort({KEY:1})
例子
假设集合test1有以下数据。
{ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习" }{ "_id" : ObjectId("6103ba645c56b69ebcf036ca"), "title" : "Java学习" }{ "_id" : ObjectId("6103ba645c56b69ebcf036cb"), "title" : "MongoDB学习" }
下面的示例,将显示按标题降序排序的文档。
> db.test1.find({},{"title":1, _id:0}).sort({"title":-1}){ "title" : "PHP学习" }{ "title" : "MongoDB 学习" }{ "title" : "Java 学习" }
注意,如果没有指定升序还是降序,那么
sort()方法将按升序排列。
MongoDB 索引
索引可以让查询更快。如果没有索引,查询文档时时,MongoDB必须扫描集合的每个文档。这种扫描效率非常低,MongoDB需要处理大量数据。
索引针对特定字段或一组字段创建。
createIndex() 方法
要创建索引,可使用createIndex()方法。
语法
createIndex()方法的基本语法如下:
db.COLLECTION_NAME.createIndex({KEY:1})
这里的键是要创建索引的字段,1表示按升序创建索引,-1表示降序。
例子
db.test1.createIndex({"title":1})
在createIndex()方法中,可以传递多个字段,该方法将在多个字段上创建索引。
db.test1.createIndex({"title":1,"description":-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 | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
MongoDB 聚合
聚合操作对查询到的记录分组,然后对每组记录进行统计计算,返回统计结果。在SQL中,count(*)配合group by可以统计每组记录的条数,就相当于MongoDB中的聚合sum。
aggregate() 方法
MongoDB中,聚合操作可以使用aggregate()方法。
语法
aggregate()方法的基本语法如下:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
例子
在test1集合中有以下数据:
> db.test1.find().pretty(){ "_id" : ObjectId("6103ba645c56b69ebcf036c9"), "title" : "PHP学习", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 200}{ "_id" : ObjectId("6103bb195c56b69ebcf036ca"), "title" : "Java 学习", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "demo", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150}{ "_id" : ObjectId("6103bb2c5c56b69ebcf036cb"), "title" : "MongoDB 学习", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "demo", "url" : "http://www.badiu.com", "tags" : [ "mongodb" ], "likes" : 100}
现在,要统计demo写了多少个教程,可以使用aggregate()方法:
> db.test1.aggregate([{$group : {_id : "$by", num_tutorial : {$sum : 1}}}]){ "_id" : "test", "num_tutorial" : 2 }
上面的例子,等价的SQL查询是
select `by`, count(*) from test1 group by `by`
在上面的例子中,按照字段by对结果进行分组,并统计分组中记录条数。下面是聚合表达式的列表:
| 表达式 | 描述 | 例子 |
|---|---|---|
| $sum | 汇总集合中文档的字段值。 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, num_tutorial : {sum:“sum : “sum:“likes”}}}]) |
| $avg | 计算集合中,所有文档中所有给定值的平均值。 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, num_tutorial : {avg:“avg : “avg:“likes”}}}]) |
| $min | 获取集合中,文档字段的最小值 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, num_tutorial : {min:“min : “min:“likes”}}}]) |
| $max | 获取集合中,文档字段的最大值 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, num_tutorial : {max:“max : “max:“likes”}}}]) |
| $push | 将全部文档的某个字段值作为数组插入到结果中。 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, url : {push:“push: “push:“url”}}}]) |
| $addToSet | 将全部文档的某个字段值作为数组插入到结果中,但字段值不重复。 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, url : {addToSet:“addToSet : “addToSet:“url”}}}]) |
| $first | 获取分组中的最后一个文档,通常,文档是有序的这个操作才有意义。 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, first_url : {first:“first : “first:“url”}}}]) |
| $last | 获取分组中的首个文档,通常,文档是有序的这个操作才有意义。 | db.test1.aggregate([{ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : “by”, last_url : {last:“last : “last:“url”}}}]) |
管道
在UNIX命令中,管道可以让某些命令的输出,作为另一个命令的输入,以此类推。MongoDB的聚合框架中也支持相同的概念,某些操作阶段输出一组文档,这些文档可以作为另一组操作阶段的输入,以此类推。
下面是聚合框架的可能阶段,可以把这些阶段串联组合起来:
-
$project — 用于从集合中选择某些字段。
-
$match — 这是一个过滤操作,过滤文档。
-
$group — 这是如上所述的实际聚合。
-
$sort — 对文档进行排序。
-
$skip – 结果偏移量,类似mysql中的offset。
-
$limit — 限定结果数量。
-
$unwind
– 用于展开使用数组的文档。例如:
{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }复制
会被展开成为:
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
MongoDB 备份数据
MongoDB数据转储
要在MongoDB中创建数据库备份,可以使用mongodump命令。这个命令将把服务器的全部数据转储到文件目录中。
语法
mongodump命令的基本语法如下
# mongodump
例子
启动mongod服务器,假设服务器运行本地主机和端口27017上。命令行中,执行mongodump
[root@qikegu ~]# mongodump
该命令将连接到运行在本地主机和端口27017的服务器,并将服务器的所有数据备份到目录./dump/。下面是命令的输出:
2021-07-10T13:12:04.913+0800 writing admin.system.version to2021-07-10T13:12:04.915+0800 done dumping admin.system.version (1 document)2021-07-10T13:12:04.915+0800 writing test.test to2021-07-10T13:12:04.915+0800 writing test.test1 to2021-07-10T13:12:04.915+0800 writing test.mycollection to2021-07-10T13:12:04.919+0800 done dumping mydb.test (0 documents)2021-07-10T13:12:04.924+0800 done dumping mydb.test1 (5 documents)2021-07-10T13:12:04.925+0800 done dumping mydb.mycollection (0 documents)
复制
下面是可以与mongodump命令一起使用的选项列表。
| 语法 | 描述 | 例子 |
|---|---|---|
| mongodump –host HOST_NAME –port PORT_NUMBER | 此命令将备份指定主机上,MongoDB服务器中的所有数据库。 | mongodump –host localhost –port 27017 |
| mongodump –dbpath DB_PATH –out BACKUP_DIRECTORY | 此命令将指定数据库备份到指定路径。 | mongodump –dbpath /data/db/ –out /data/backup/ |
| mongodump –collection COLLECTION –db DB_NAME | 此命令只备份指定数据库的指定集合。 | mongodump –collection mycol –db test |
恢复数据
要恢复备份数据,使用mongorestore命令。此命令从备份目录中还原所有数据。
语法
mongorestore命令的基本语法是
# mongorestore
下面是命令的输出:
[root@kali ~]# mongorestore
2021-07-10T13:22:23.355+0800 using default 'dump' directory
2021-07-10T13:22:23.356+0800 preparing collections to restore from
2021-07-10T13:22:23.357+0800 reading metadata for mydb.qikegu from dump/test/test1.metadata.json
2021-07-10T13:22:23.358+0800 restoring test.test1 from dump/test/test1.bson
2021-07-10T13:22:23.358+0800 reading metadata for test.mycollection from dump/test/test1.metadata.json
2021-07-10T13:22:23.358+0800 restoring mydb.test1 from dump/mydb/mycollection.bson
2021-07-10T13:22:23.358+0800 reading metadata for test.mycollection from dump/test/mycollection.metadata.json
2021-07-10T13:22:23.361+0800 restoring mydb.mycollection3 from dump/test/mycollection.bson
2021-07-10T13:22:23.363+0800 no indexes to restore
2021-07-10T13:22:23.364+0800 finished restoring test.test1 (0 documents)
2021-07-10T13:22:23.364+0800 no indexes to restore
2021-07-10T13:22:23.364+0800 finished restoring test.mycollection (0 documents)
2021-07-10T13:22:23.368+0800 error: multiple errors in bulk operation:
- E11000 duplicate key error collection: test.test1 index: _id_ dup key: { : ObjectId('6103ba645c56b69ebcf036c9') }
- E11000 duplicate key error collection: test.test1 index: _id_ dup key: { : ObjectId('6103ba645c56b69ebcf036ca') }
- E11000 duplicate key error collection: test.test1 index: _id_ dup key: { : ObjectId('6103ba645c56b69ebcf036cb') }
2021-07-10T13:22:23.368+0800 restoring indexes for collection test.test1 from metadata
2021-07-10T13:22:23.368+0800 finished restoring mydb.qikegu (5 documents)
2021-07-10T13:22:23.368+0800 done

浙公网安备 33010602011771号