安装 MongoDB
安装依赖包
sudo yum install libcurl openssl
下载
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.3.tgz # 服务包
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel70-x86_64-100.5.1.tgz # 工具包
tar -zxvf mongodb-linux-x86_64-rhel70-5.0.3.tgz
mv mongodb-linux-x86_64-rhel70-5.0.3 mongodb-5.0.3
export PATH=/data/mongodb-5.0.3/bin:$PATH
启动
[root@pt-004 data]# mkdir -p /var/lib/mongodb
[root@pt-004 data]# mkdir -p /var/log/mongodb
[root@pt-004 data]# mongod --dbpath /var/lib/mongodb --logpath /var/log/mongodb/mongod.log --fork
about to fork child process, waiting until server is ready for connections.
forked process: 28487
child process started successfully, parent exiting
MongoDB 后台管理 Shell
当你进入 mongoDB 后台后,它默认会链接到 test 文档(数据库):
[root@pt-004 data]# mongo
MongoDB shell version v5.0.3
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("6cd55314-5e3a-4245-87c5-7f677bc75adc") }
MongoDB server version: 5.0.3
================
Welcome to the MongoDB shell.
---
>
由于它是一个JavaScript shell,您可以运行一些简单的算术运算:
> 2+2
4
> 3+6
9
现在让我们插入一些简单的数据,并对插入的数据进行检索:
> db.runoob.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.runoob.find()
{ "_id" : ObjectId("614cdbb38974bb4535521224"), "x" : 10 }
>
第一个命令将数字 10 插入到 runoob 集合的 x 字段中。
停止 mongodb
mongod --dbpath /var/lib/mongodb --logpath /var/log/mongodb/mongod.log --shutdown
也可以在 mongo 的命令中实现:
> use admin
switched to db admin
> db.shutdownServer()
1、创建数据库
语法:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
实例:
创建数据库student
> use student
switched to db student
> db
student
>
可以使用 show dbs 命令查看所有数据库:
> db.stu.insert({"name":"xiaozhang"})
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
student 0.000GB
>
MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
2、删除数据库
语法:
db.dropDatabase()
删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。
3、创建集合
语法:
db.createCollection(name, options)
参数说明:
- name: 要创建的集合名称
- options: 可选参数, 指定有关内存大小及索引的选项
options 可以是如下参数:
字段 | 类型 | 描述 |
---|---|---|
capped | 布尔 | (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。 |
size | 数值 | (可选)为固定集合指定一个最大值,即字节数。 如果 capped 为 true,也需要指定该字段。 |
max | 数值 | (可选)指定固定集合中包含文档的最大数量。 |
在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。
实例:
在student数据库中创建集合
> db
student
> db.createCollection("best")
{ "ok" : 1 }
如果要查看已有集合,可以使用 show collections 或 show tables 命令:
> show collections
best
stu
>
在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
4、删除集合
语法:
db.collection.drop()
实例:
在数据库 student 中,我们通过 show collections 命令查看已存在的集合,删除集合
> show collections
best
stu
> db.best.drop()
true
> show collections
stu
>
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
5、插入文档
文档的数据结构和 JSON 基本一样。
所有存储在集合中的数据都是 BSON 格式。
BSON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。
语法:
db.COLLECTION_NAME.insert(document)
- insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。
db.collection.insertOne() 用于向集合插入一个新文档,语法格式如下:
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
db.collection.insertMany() 用于向集合插入一个多个文档,语法格式如下:
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
参数说明:
- document:要写入的文档。
- writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
- ordered:指定是否按顺序写入,默认 true,按顺序写入。
实例:
将以下文档插入 MongoDB 的 student 数据库 的 col 集合中:
> db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: 'Penguin',
url: 'https://www.pengtao.vip',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
> db.col.insert({title: 'Java 教程',
description: 'Java 是一个高级程序设计语言',
by: 'Penguin',
url: 'https://www.pengtao.vip',
tags: ['java'],
likes: 150
})
查看已插入文档:
> db.col.find()
{ "_id" : ObjectId("619d70192eea9d72d3b511b7"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Penguin", "url" : "https://www.pengtao.vip", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
{ "_id" : ObjectId("619d91a312311e4ca6a69607"), "title" : "Java 教程", "description" : "Java 是一个高级程序设计语言", "by" : "Penguin", "url" : "https://www.pengtao.vip", "tags" : [ "java" ], "likes" : 150 }
>
我们也可以将数据定义为一个变量
> document=({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: 'Penguin',
url: 'https://www.pengtao.vip',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
});
然后执行插入操作:
> db.col.insert(document)
WriteResult({ "nInserted" : 1 })
>
insertOne() 插入单个文档
> var document = db.collection.insertOne({"name":"zhangsan"})
> document{
"acknowledged" : true,
"insertedId" : ObjectId("619d725f2eea9d72d3b511b8")
}
insertMany() 插入多个文档
> var res = db.collection.insertMany([{"name":"lisi"}, {"addr":"beijng"}])
> res
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("619d72af2eea9d72d3b511b9"),
ObjectId("619d72af2eea9d72d3b511ba")
]
}
6、更新文档
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.find()
{ "_id" : ObjectId("619d6e872eea9d72d3b511b6"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Penguin", "url" : "https://www.pengtao.vip", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
> db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.col.find().pretty()
{
"_id" : ObjectId("619d6e872eea9d72d3b511b6"),
"title" : "MongoDB",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "Penguin",
"url" : "https://www.pengtao.vip",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
可以看到标题(title)由原来的 “MongoDB 教程” 更新为了 “MongoDB”。
以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。
> db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
数据存在则更新:
db.collection.update({'title':'MongoDB 教程'}, {$set: {'title':'MongoDB'}})
数据存在时不进行操作:
db.collection.update({'title':'MongoDB 教程'}, {$setOnInsert: {'title':'MongoDB'}})
以上可扩展为多个字段(查询,更新),如果数据不存在需要插入,设置 upsert:true 即可:
db.collection.update({'title':'MongoDB 教程'}, {$set: {'title':'MongoDB'}},{upsert:true})
在3.2版本开始,MongoDB提供以下更新集合文档的方法:
- db.collection.updateOne() 向指定集合更新单个文档
- db.collection.updateMany() 向指定集合更新多个文档
首先我们在test集合里插入测试数据
> use test
> db.test_collection.insert( [
{"name":"abc","age":"25","status":"zxc"},
{"name":"dec","age":"19","status":"qwe"},
{"name":"asd","age":"30","status":"nmn"},
] )
更新单个文档
> db.test_collection.updateOne({"name":"abc"},{$set:{"age":"28"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.test_collection.find()
{ "_id" : ObjectId("59c8ba673b92ae498a5716af"), "name" : "abc", "age" : "28", "status" : "zxc" }
{ "_id" : ObjectId("59c8ba673b92ae498a5716b0"), "name" : "dec", "age" : "19", "status" : "qwe" }
{ "_id" : ObjectId("59c8ba673b92ae498a5716b1"), "name" : "asd", "age" : "30", "status" : "nmn" }
>
更新多个文档
> db.test_collection.updateMany({"age":{$gt:"10"}},{$set:{"status":"xyz"}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
> db.test_collection.find()
{ "_id" : ObjectId("59c8ba673b92ae498a5716af"), "name" : "abc", "age" : "28", "status" : "xyz" }
{ "_id" : ObjectId("59c8ba673b92ae498a5716b0"), "name" : "dec", "age" : "19", "status" : "xyz" }
{ "_id" : ObjectId("59c8ba673b92ae498a5716b1"), "name" : "asd", "age" : "30", "status" : "xyz" }
>
7、删除文档
MongoDB remove() 函数是用来移除集合中的数据。
语法:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
参数说明:
- query :(可选)删除的文档的条件。
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
实例:
移除 title 为 ‘MongoDB’ 的文档:
> db.col.remove({'title':'MongoDB'})
WriteResult({ "nRemoved" : 1 })
删除所有数据:
> db.col.remove({})
现在官方推荐使用 deleteOne() 和 deleteMany() 方法。
如删除集合下全部文档:
db.col.deleteMany({})
删除 status 等于 A 的全部文档:
db.col.deleteMany({ status : "A" })
删除 status 等于 D 的一个文档:
db.col.deleteOne( { status: "D" } )
8、查询文档
MongoDB 查询文档使用 find() 方法。
语法:
db.collection.find(query, projection)
- query :可选,使用查询操作符指定查询条件
- projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
> db.col.find().pretty()
pretty() 方法以格式化的方式来显示所有文档。
MongoDB 与 RDBMS Where 语句比较
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:
操作 | 格式 | 范例 | RDBMS中的类似语句 |
---|---|---|---|
等于 | {<key>:<value> } | db.col.find({"by":"Penguin"}).pretty() | where by = 'Penguin' |
小于 | {<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 |
MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
语法格式如下:
> db.col.find({key1:value1, key2:value2}).pretty()
实例:
> db.col.find({"by":"Penguin", "title":"MongoDB 教程"}).pretty()
{
"_id" : ObjectId("619d70192eea9d72d3b511b7"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "Penguin",
"url" : "https://www.pengtao.vip",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
以上实例中类似于 WHERE 语句:WHERE by=‘Penguin’ AND title='MongoDB 教程’
MongoDB OR 条件
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
实例:
以下实例中,我们演示了查询键 by 值为 Penguin 或键 title 值为 MongoDB 教程 的文档。
> db.col.find({$or:[{"by":"Penguin"},{"title": "MongoDB 教程"}]}).pretty()
{
"_id" : ObjectId("619d70192eea9d72d3b511b7"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "Penguin",
"url" : "https://www.pengtao.vip",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
AND 和 OR 还可联合使用
> db.col.find({"likes": {$gt:50}, $or: [{"by": "Penguin"},{"title": "MongoDB 教程"}]}).pretty()
类似常规 SQL 语句为: 'where likes>50 AND (by = ‘Penguin’ OR title = ‘MongoDB 教程’)'
projection 参数的使用方法
db.collection.find(query, projection)
若不指定 projection,则默认返回所有键,指定 projection 格式如下,有两种模式
db.collection.find(query, {title: 1, by: 1}) // inclusion模式 指定返回的键,不返回其他键
db.collection.find(query, {title: 0, by: 0}) // exclusion模式 指定不返回的键,返回其他键
_id 键默认返回,需要主动指定 _id:0 才会隐藏
两种模式不可混用(因为这样的话无法推断其他键是否应返回)
db.collection.find(query, {title: 1, by: 0}) // 错误
只能全1或全0,除了在inclusion模式时可以指定_id为0
db.collection.find(query, {_id:0, title: 1, by: 1}) // 正确
9、条件操作符
条件操作符用于比较两个表达式,MongoDB中条件操作符有:
- (>) 大于 - $gt
- (<) 小于 - $lt
- (>=) 大于等于 - $gte
- (<= ) 小于等于 - $lte
MongoDB (>) 大于操作符 - $gt
如果你想获取 “col” 集合中 “likes” 大于 100 的数据,你可以使用以下命令:
db.col.find({likes : {$gt : 100}})
类似于SQL语句:
select * from col where likes > 100;
MongoDB(>=)大于等于操作符 - $gte
如果你想获取"col"集合中 “likes” 大于等于 100 的数据,你可以使用以下命令:
db.col.find({likes : {$gte : 100}})
类似于SQL语句:
Select * from col where likes >=100;
MongoDB (<) 小于操作符 - $lt
如果你想获取"col"集合中 “likes” 小于 150 的数据,你可以使用以下命令:
db.col.find({likes : {$lt : 150}})
类似于SQL语句:
select * from col where likes < 150;
MongoDB (<=) 小于等于操作符 - $lte
如果你想获取"col"集合中 “likes” 小于等于 150 的数据,你可以使用以下命令:
db.col.find({likes : {$lte : 150}})
类似于SQL语句:
select * from col where likes <= 150;
MongoDB 使用 (<) 和 (>) 查询 - $lt 和 $gt
如果你想获取"col"集合中 “likes” 大于100,小于 200 的数据,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
类似于SQL语句:
select * from col where likes>100 AND likes<200;
模糊查询
查询 title 包含"教"字的文档:
db.col.find({title:/教/})
查询 title 字段以"教"字开头的文档:
db.col.find({title:/^教/})
查询 titl e字段以"教"字结尾的文档:
db.col.find({title:/教$/})
10、Limit、Skip、Sort方法
Limit() 方法
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
语法:
>db.COLLECTION_NAME.find().limit(NUMBER)
实例:
查询文档中的两条记录
> db.col.find({},{"title":1,_id:0}).limit(2)
{ "title" : "MongoDB 教程" }
{ "title" : "Java 教程" }
>
补充说明:
- 第一个 {} 放 where 条件,为空表示返回集合中所有文档。
- 第二个 {} 指定那些列显示和不显示 (0表示不显示 1表示显示)。
Skip() 方法
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
语法:
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
实例:
以下实例只会显示第二条文档数据
> db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }
>
sort() 方法
在 MongoDB 中使用 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" : "Java 教程" }
{ "title" : "MongoDB 教程" }
>
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()。
11、索引
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。
createIndex() 方法
MongoDB使用 createIndex() 方法来创建索引。
语法:
>db.collection.createIndex(keys, options)
语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
实例:
> db.col.createIndex({"title":1})
createIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
> db.col.createIndex({"title":1,"description":-1})
createIndex() 接收可选参数,可选参数列表如下:
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。 |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
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.col.getIndexes()
查看集合索引大小
db.col.totalIndexSize()
删除所有集合索引
db.col.dropIndexes()
删除集合指定索引
db.col.dropIndex("索引名称")
利用 TTL 集合对存储的数据进行失效时间设置,数据记录中 createDate 为日期类型时,设置时间180秒后自动清除。
db.col.createIndex({"createDate": 1},{expireAfterSeconds: 180})
12、聚合
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
有点类似 SQL 语句中的 count(*)。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。
语法:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
实例:
计算每个作者所写的文章数,使用aggregate()计算结果如下:
> db.col.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
"result" : [
{
"_id" : "mongodb",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
>
以上实例类似sql语句:
select by_user as _id, count(*) as num_tutorial from col group by 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"}}}]) |
管道
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
- $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
- $ match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
- $limit:用来限制MongoDB聚合管道返回的文档数。
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
- $group:将集合中的文档分组,可用于统计结果。
- $sort:将输入文档排序后输出。
- $geoNear:输出接近某一地理位置的有序文档。
管道操作实例:
1、$project实例
db.article.aggregate(
{ $project : {
title : 1 ,
author : 1 ,
}}
);
这样的话结果中就只还有id,tilte和author三个字段了,默认情况下id字段是被包含的,如果要想不包含id话,可以指定id的值为0,即 ” __id : 0“
2.$match实例
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
$ match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
当 match 条件和 group 同时存在时,顺序会影响检索结果,必须先写 match 在前面。
3.$skip实例
db.article.aggregate(
{ $skip : 5 });
经过$skip管道操作符处理后,前五个文档被"过滤"掉。
13、备份与恢复
MongoDB从 4.4 版本开始将服务器与工具包分开,所以使用备份恢复得单独安装工具包:
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel70-x86_64-100.5.1.tgz
备份(mongodump)
在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中。
mongodump命令可以通过参数指定导出的数据量级转存的服务器。
语法:
mongodump命令脚本语法如下:
mongodump -h dbhost -d dbname -o dbdirectory
-
-h:
MongoDB 所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-
-d:
需要备份的数据库实例,例如:test
-
-c:
指明集合的名字,如:col
-
-o:
备份的数据存放位置,例如:/data/dump,该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
实例:
mongodump -d student -o /data/mongodb-5.0.3/dump/
恢复(mongorestore)
mongodb使用 mongorestore 命令来恢复备份的数据。
语法:
mongorestore命令脚本语法如下:
[root@rac3 dump]# mongorestore -h <hostname><:port> -d dbname <path>
-
–host <:port>, -h <:port>:
MongoDB所在服务器地址,默认为: localhost:27017
-
-d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
-
–drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
-
< path>:
mongorestore 最后的一个参数,设置备份数据所在位置,例如:/data/dump/test。
你不能同时指定 < path> 和 --dir 选项,–dir也可以设置备份目录。
-
–dir:
指定备份的目录,你不能同时指定 < path> 和 --dir 选项。
实例:
[root@rac3 dump]# mongorestore -d stu2 /data/mongodb-5.0.3/dump/student/