快速入门
是跨平台、文档型(对象)的数据库(NoSQL),提供高性能,高可用和易于扩展。(Mongo工作在集合和文档上的一种概念)
MongoDB 和 MySQL的对应关系:
db(数据库) | database(数据库) |
collection(集合) | table(表) |
Document(文档的数据结构和JSON基本一样,所有存储在集合中的数据都是BSON格式) BSON是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。 |
安装(略过)
配置文件详情:mongod.conf
dbpath=/data/app/mongodb4.2.8/data/rs3 #mongo数据安装目录
logpath=/data/app/mongodb4.2.8/log/rs3.log #日志打印的目录
journal=true #数据是否故障恢复
port=27002 #端口
replSet=rs #复制集名称
logappend=true #复制集日志是以追加的方式进行
fork = true #是否后台启动
bind_ip=0.0.0.0 # 绑定主机
maxConns=15000 # 设置最大连接数
wiredTigerCacheSizeGB=8 # 显示最大的使用内存为8g
engine=wiredTiger # 设置存储引擎
数据类型
字符串 | 使用最多的类型,必须是utf8 |
整型 | 存储数值,可以是32位或64位,具体取决于服务器 |
布尔类型 | 存储布尔值(true / false ) |
数组 | 将数组或列表或多个值存储到一个键中 |
时间戳(ctimestamp) | 当文档被修改或添加时,可以方便地进行录制。 |
对象 | 用于嵌入式文档 |
Null | 用于存储Null |
对象ID | 用于存储文档的ID |
二进制数据 | 用于存储二进制数据 |
正则表达式 | 用于存储正则表达式 |
基本命令使用
MongoDB帮助:db.help()
获取有关MongoDB服务器的统计信息:db.stats()
创建数据库:use mydb
查看当前使用的数据库:db(默认数据库是test)
查询数据库列表:show dbs
删除当前数据库:db.dropDatabase()
创建集合:db.createCollection("mycollection") # 一般不需要创建集合,当插入文档时,MongoDB会自动创建集合。
查看所有集合:show collections
删除集合:db.mycollection.drop()
插入文档
db.dmp_phone.insert({ "phone" : "13552297881", "province" : 61, "city" : 5223, "label_id" : "appid-00002", "createTime" : 1592141063, "lock" : 0, "updateTime" : 1594286430 })
或者
db.dmp_phone.save({ "phone" : "13295412258", "province" : 37, "city" : 3705, "label_id" : "wx-00002", "createTime" : 1592211865, "lock" : 0, "updateTime" : 1594286430 })
注意:在插入的文档中,如果不指定 _id 参数,那 MongoDB 会为此文档分配一个唯一的ObjectId。
_id为集合中的每个文档唯一的12个字节的十六进制数。 12字节划分如下:
_id: ObjectId(4 bytes timestamp, 3 bytes machine id, 2 bytes process id, 3 bytes incrementer)
3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。
db.dmp_phone.insertOne({ "phone" : "13552297881", "province" : 61, "city" : 5223, "label_id" : "appid-00002", "createTime" : 1592141063, "lock" : 0, "updateTime" : 1594286430 })
db.dmp_phone.insertMany([{ "phone" : "13552297881", "province" : 61, "city" : 5223, "label_id" : "appid-00002", "createTime" : 1592141063, "lock" : 0, "updateTime" : 1594286430 },
{ "phone" : "13295412258", "province" : 37, "city" : 3705, "label_id" : "wx-00002", "createTime" : 1592211865, "lock" : 0, "updateTime" : 1594286430 }])
查询文档
1.find()方法:返回一个文档的List
db.COLLECTION_NAME.find(document)
db.mycol.find().pretty()
db.mycol.find().pretty()
2.findOne()方法:只返回一个文档
MongoDB 与 RDBMS的等效 Where 子句:
操作 | 语法 | 示例 | RDBMS等效语句 |
相等 | {<key>:<value>} | db.mycol.find({"by":"yiibai"}).pretty() | where by = 'yiibai' |
小于 | {<key>:{$lt:<value>}} | db.mycol.find({"likes":{$lt:50}}).pretty() | where likes < 50 |
小于等于 | {<key>:{$lte:<value>}} | db.mycol.find({"likes":{$lte:50}}).pretty() | where likes <= 50 |
大于 | {<key>:{$gt:<value>}} | db.mycol.find({"likes":{$gt:50}}).pretty() | where likes > 50 |
大于等于 | {<key>:{$gte:<value>}} | db.mycol.find({"likes":{$gte:50}}).pretty() | where likes >= 50 |
不等于 | {<key>:{$ne:<value>}} | db.mycol.find({"likes":{$ne:50}}).pretty() | where likes != 50 |
MongoDB中的AND操作符
db.dmp_phone.find(
{
$and: [
{"province": 61}, {"city": 5223}
]
}
).pretty()
MongoDB中的OR操作符
db.dmp_phone.find(
{
$or: [
{"province": 61}, {"city": 5223}
]
}
).pretty()
使用 AND 和 OR 条件一起
等价SQL:
SELECT * FROM dmp_phone where phone="13552297881" AND(province =61 OR city =2309)
db.dmp_phone.find(
{"phone": "13552297881"},
{
$or: [
{"province": 61}, {"city": 2309}
]
}
).pretty()
查询嵌入、嵌套文档
db.dmp_phone.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
])
匹配嵌入、嵌套文档
要在作为嵌入/嵌套文档的字段上指定相等条件,请使用查询过滤器文档{<field>:<value>}
,其中<value>
是要匹配的文档。
1. 查询选择字段size
等于{ h: 14, w: 21, uom: "cm" }
的所有文档:
db.dmp_phone.find(
{size: { h: 14, w: 21, uom: "cm" }}
).pretty()
整个嵌入式文档中的相等匹配需要精确匹配指定的<value>
文档,包括字段顺序。
2. 查询集合当中不匹配的文档:
db.dmp_phone.find(
{size: { w: 21,h: 14, uom: "cm" }}
).pretty()
查询嵌套字段
要在嵌入/嵌套文档中的字段上指定查询条件,请使用点符号(“field.nestedField
”)。
在嵌套字段上指定等于匹配
以下示例选择在size
字段中嵌套的字段uom
等于“in
”的所有文档:
db.dmp_phone.find(
{ "size.uom":"in"}
).pretty()
使用查询运算符指定匹配
查询使用size
字段中嵌入的字段h
中的小于运算符($lt
):
db.dmp_phone.find(
{ "size.h": {$lt :15}}
).pretty()
指定AND条件
查询选择嵌套字段h
小于15
的所有文档,嵌套字段uom
等于“in
”,status
字段等于“D
”:
db.dmp_phone.find(
{ "size.h": {$lt :15},"size.uom": "in", status: "D"}
).pretty()
更新文档
1.update()方法:更新现有文档中的值
2.save()方法:传递的文档数据替换现有文档
删除文档
remove()方法:从集合中删除文档,remove()方法接受两个参数。 一个是删除条件,第二个是标志:justOne。
1. criteria - (可选)符合删除条件的集合将被删除。
2. justOne - (可选)如果设置为true或1,则只删除一个文档。
示例将删除_id为“100”的文档。
b.mycol.remove({'_id':100})
只删除一条文档记录(设置justOne参数)
db.mycol.remove(DELETION_CRITERIA,1)
删除所有文档记录
db.mycol.remove()
投影(选择字段)
投影表示仅选择所需要字段的数据,而不是选择整个文档字段的数据。
在MongoDB中,当执行find()
方法时,它默认将显示文档的所有字段。为了限制显示的字段,需要将字段列表对应的值设置为1
或0
。1
用于显示字段,而0
用于隐藏字段。
db.dmp_phone.find({},
{"phone":1,"city":1}
)
注意,在执行find()
方法时,始终都会显示_id
字段,如果不想要此字段,则需要将其设置为0
db.dmp_phone.find({},
{"_id":0,"phone":1,"city":1}
)
限制记录数
1. 要限制MongoDB中返回的记录数,需要使用 limit() 方法,该方法接受一个数字类型参数,就是要显示的文档数。
语法:
db.dmp_phone.find().limit(num)
2. skip()方法也接受数字类型的参数,用于跳过文档数量。
示例将直接显示第三个文档:
db.dmp_phone.find().limit(1).skip(2)
注意:skip()方法中的默认值为0
排序记录
使用 sort() 方法进行文档排序,该方法接受包含字段列表及其排序顺序的文档。使用指定排序顺序 1 和 -1,1用于升序,而-1用于降序。
将 _id 按照升序排序
db.dmp_phone.find(
{},
{"_id":1,"phone" :1}
).sort({"_id":1})
索引
创建索引的目的:提高查询效率,如果没有创建索引,MongoDB必须扫描集合的每个文档,来选择与查询语句匹配的文档,这种扫描效率极低。
索引是特殊的数据结构,索引存储特定字段或一组字段的值,按照索引中指定的字段值进行排序。
语法:db.COLLECTION_NAME.ensureIndex({KEY:1})
这里的key是要在其上创建索引的字段的名称,1是升序。 要按降序创建索引,需要使用-1
创建索引:
db.mycol.ensureIndex({"title":1})
同时也支持传入多个字段,用以在多个字段上创建索引。
db.mycol.ensureIndex({"title":1,"description":-1})
查看已有的索引数量:
db.dmp_phone.getIndexes()
删除索引:
db.dmp_phone.dropIndex("phone_1")
聚合
MongoDB中的聚合应该使用 aggregate() 方法。
模拟数据:
db.article.insert([
{
_id: 100,
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'Maxsu',
url: 'http://www.yiibai.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
_id: 101,
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'Maxsu',
url: 'http://www.yiibai.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
_id: 102,
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Kuber',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
},
{
_id: 103,
title: 'MySQL Overview',
description: 'MySQL is sql database',
by_user: 'Curry',
url: 'http://www.yiibai.com/mysql/',
tags: ['MySQL', 'database', 'SQL'],
likes: 350
}])
如果想知道每个用户写了多少教程,那么此时就可以使用 aggregate() 方法。
db.article.aggregate([
{$group :
{_id : "$by_user", num_tutorial : {$sum : 1}}
}
])
等效的SQL语句为:
select by_user, count(*) as num_tutorial from `article` group by by_user;
表达式 | 描述 | 示例 |
$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 | 根据分组从源文档获取第一个文档。 通常情况下,这只适用于以前应用的“$sort ”阶段。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根据分组从源文档获取最后一个文档。通常情况下,这只适用于以前应用的“$sort ”阶段。 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
复制
分片
备份与恢复
部署
1. bin/mongostat:检查所有运行的mongod实例的状态,并返回数据库操作的计数器。
这些计数器包括插入,查询,更新,删除和游标。 命令还显示遇到页面错误,并显示锁定百分比。这可以用来监控内存不足,写入容量或出现性能问题。
2. bin/mongotop 5:此命令跟踪并报告基于集合的MongoDB实例的读写活动,默认情况下,mongotop会在每秒钟内返回信息,但是可相应的更改信息。应该检查此读写活动是否符合您的应用意图,并且要一次对数据库发出太多的
写入操作,从磁盘读取的频率太高,或者超出了工作集合的大小。