MongoDB
一、关系型数据库与MongoDB对比
关系型数据库 MongoDB 解释说明
database database 数据库
table collection 数据表/集合
row document 数据行/文档
column field 字段/域
index index 索引
table joins 表连接,MongoDB中不支持
primary key primary key 主键,MongoDB会自动将_id字段设置为主键
二、数据类型
数据类型 描述
String 字符串类型,最常用的,在MongoDB中,只有UTF-8编码的字符串才是合法的
Integer 整型,分为32位或64位两种
Boolean 布尔型,true/false
Double 双精度浮点型,用于存储小数数据
Min/Max Keys 将一个值与BSON元素的最低值和最大值相对比
Array 数组类型,将数组、列表或多个值存储在一个键中
Timestamp 时间戳,记录文档修改或添加的具体时间
Object 用于内嵌文档
Null 用于创建空值
Symbol 符号,该数据类型与字符串类型类似,不同的是,它一般用于采用特殊符号类型的语言
Date 日期时间
Object ID 对象ID,用于创建文档的ID
Binary Data 二进制数据,用于存储二进制数据
code 代码类型,用于在文档中存储JavaScript代码
Regular expression 正则表达式类型,用于存储正则表达式
比较重要的几个数据类型:
Object ID由12字节的字符组成,其中:
前4个字节表示当前的Unix时间戳;
之后的3个字节是当前设备的机器识别码;
再之后的2个字节是MongoDB服务器的进程id;
最后3个字节为计数器,计数器的起始值随机获得;
Timestamp:在MongoDB的内部使用,由一个64位值构成,其中:
前32位是一个Unix时间戳(由Unix纪元(1970.1.1)开始到现在经过的秒数);
后32位是一秒内的操作序数。
Date:是一个64位的对象,存放从1970.1.1开始到现在经历的毫秒,负值表示1970.1.1之前的时间。
三、数据模型
1、嵌入式数据模型:所有相关的数据存储到一个文档中,也称非模范化数据模型。
2、规范化数据模型:通过引用将原始文档与子文档关联起来。
四、MongoDB连接数据库
1、标准URL连接语法如下所示:mongodb://[username:password@]host1[:port1] [,host2[:port2],...[,hostn[:portn]]] [/[database]] [?options]
2、语法说明如下:
mongodb:// 固定格式,必须指定
username:password@ 可选项,如果设置,以指定的用户名,密码登录数据库
host1 必填参数,用来指定要连接服务器的地址
portx 可选项,用来指定端口,如果不填,默认为27017
/database 可选项,指定的数据库,若不指定,则默认打开test数据库
?options 可选项,用来定义连接选项,如果不使用/database,则前面需要使用/与前面的内容分隔,所有连接选项都是键值对name=value的形式,键值对之间通通用&或;(分号)隔开
五、MongoDB创建数据库
1、use命令:如果数据库不存在,则会创建一个新的数据库,如果已存在,则将切换到该数据库。语法如下:
use database_name
2、db命令:查看当前选择的数据库。
show dbs:查看MongoDB中所有的数据库。
3、MongoDB默认的数据库为test,如果没有创建新的数据库或者选择其他数据库,集合将默认存放再test数据库中。
4、在MongoDB中,集合只有在内容插入后才会创建,即创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
六、MongoDB删除数据库
1、show dbs:查看所有数据库
2、use biancheng:切换到要删除的数据库
3、db.dropDatabase():删除当前数据库
七、MongoDB创建集合
1、集合没有固定的结构,可以向集合中插入不同格式或类型的数据。
2、db.createCollection(name,options)方法创建集合
name:创建的集合名称
options:可选参数,如下:
capped:布尔类型,如果为true,则创建固定集合,固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档,注意:如果该值为true,则必须指定size参数。
autoIndexId:布尔类型,如果为true,则自动在_id字段创建索引,默认为false,注意:MongoDB3.2之后不再支持该参数。
size:数值类型,为固定集合指定一个最大值,即字节数,如果capped为true,则需要指定该字段。
max:数值类型,指定固定集合中包含文档的最大数量。
3、当向集合插入文档时,MongoDB会首先检查固定集合的size字段,然后检查max字段。
4、查看集合:show collections或show tables
5、创建集合示例:db.createCollection("mycol",{capped:true,autoIndexId:true,size:102400,max=1000}){"name":"张三","age":27}
6、通常不需要手动创建集合,因为插入文档时,MongoDB会自动创建集合。
db.website.insert({"name":"编程帮","url":"www.biancheng.net"})
八、MongoDB删除集合
db.collection_name.drop():collection_name为要删除的集合名称。
九、MongoDB插入文档
1、文档是MongoDB中数据的基本单位,由BSON格式(一种计算机数据交换格式,类似于JSON)的键/值对组成。
2、向集合中插入文档:db.collection_name.insert(document)、db.collection_name.save(document)
语法说明:save():如果_id主键存在则更新数据,如果不存在就插入数据,但是在新版MongoDB中已废弃该方法,可以使用insertOne()或replaceOne()方法来代替。
insert():若插入数据的主键已存在,则会抛出org.springframework.dao.DuplicateKeyException异常,并提示主键重复,不保存当前数据。
3、使用db.use.find()查看集合use中的文档内容。
4、文档中_id为主键ID,如果不指定 _id,MongoDB则会为此文档自动分配一个唯一的 _id。
5、insertOne()方法:将一个文档插入到集合中。
insertMany()方法:将多个文档插入到集合中。
十、MongoDB查询文档
1、find()方法:将查询结果以非结构化的方式展示出来。
db.collection_name.find(query,projection)
query:可选参数,使用查询操作符指定查询条件;
projection:可选参数,使用投影操作符指定返回的键。查询时若要返回文档中所有键值,只需省略该参数即可(默认省略);
2、pretty()方法:格式化查询到的结果
db.collection_name.find(query,projection).pretty()
3、findOne()方法:仅能返回一个查询到的文档
db.collection_name.findOne(query,projection)
4、条件查询:MongoDB中条件查询于关系型数据库中where字句的比较:
操作 | 格式 | 范例 | 关系型数据库中的类似语句 |
---|---|---|---|
等于 | {<key>:<value>} | db.col.find({"by":"编程帮"}) | where by = '编程帮' |
小于 | {<key>:{$It:<value>}} | db.col.find({"like":{$It:50}}) | where like < 50 |
小于或等于 | {<key>:{$Ite:<value>}} | db.col.find({"like":{$Ite:50}}) | where like <= 50 |
大于 | {<key>:{$gt:<value>}} | db.col.find({"like":{$gt:50}}) | where like > 50 |
大于或等于 | {<key>:{$gte:<value>}} | db.col.find({"like":{$gte:50}}) | where like >= 50 |
不等于 | {<key>:{$ne:<value>}} | db.col.find({"like":{$ne:50}}) | where like != 50 |
数组中的值 | {<key>:{$in:[<value1>,<value1>,...<value>]}} | db.col.find({"title":{$in:["编程帮","MongoDB教程"]}}) | where title in("编程帮","MongoDB教程") |
不在数值中的值 | {<key>:{$nin:[<value1>,<value1>,...<value>]}} | db.col.find({"title":{$nin:["编程帮","MongoDB教程"]}}) | where title not in("编程帮","MongoDB教程") |
5、AND条件语句:
db.collection_name.find({$and:[{<key1>:<value1>},{<key2>:<value2>}...]})
示例:db.mycol.find({$and:[{title:"MongoDB教程"},{by:"编程帮"}]}).pretty();
也可以省略$and关键字。
6、OR条件语句:
db.collection_name.find({$or:[{<key1>:<value1>},{<key2>:<value2>}...]})
示例:db.mycol.find({$or:[{title:"MongoDB教程"},{by:"编程帮"}]}).pretty();
7、AND和OR联合使用:
where likes >100 AND (by = '编程帮' OR title = 'MongoDB教程')
即db.mycol.find({$and:[{"likes":{$gt:100}},$or:[{"by":"编程帮"},{"title","MongoDB教程"}]]})
十一、MongoDB更新文档
1、update()方法:用于更新现在文档中的值,语法格式如下:
db.collection_name.update(
<query>,
<update>,
{
upset:<boolean>,
multi:<boolean>,
writeConcern:<document>
}
)
参数说明如下:
query:update的查询条件,类似SQL中update语句内where后面的内容。
update:update的对象和一些更新的操作符(如$、$inc...)等,也可以理解为SQL中update语句内set后面的内容。
upset:可选参数,默认值为false,用来定义当要更新的记录不存在时,是否当作新纪录插入到集合中,当值为true时表示插入,值为false时不插入。
multi:可选参数,默认值为false,用来表示只更新找到的第一条记录,当值为true时,则把按条件查出来的多条记录全部更新。
writeConcern:可选参数,用来定义抛出异常的级别。
十二、MongoDB删除文档
1、remove()方法:从集合中删除文档,语法格式如下:
db.collection_name.remove(
<query>,
{
justOne:<boolean>,
writeConcern:<document>
}
)
参数说明如下:
query:可选参数,定义要删除文档的条件
justOne:可选参数,如果设为true或1,则只删除一个文档,如果不设置该参数,或使用默认值false,则删除所有匹配条件的文档。
writeConcern:可选参数,定义抛出异常的级别。
十三、MongoDB投影(指定查询字段)
1、db.collection_name.find(query,{key1:1,key2:1,...})
语法说明如下:
query:可选参数,使用查询操作符指定的查询条件
key1、key2、...:为要查询或者隐藏的字段,当值为1时表示显示该字段,值为0时表示隐藏该字段
2、注意:如果仅需要设置第二个参数,而不需要设置第一个参数的话,则需要在第一个参数的位置添加一个空的花括号{}作为占位符,例如:db.collection_name.find({},{_id:1})。
十四、MongoDB的limit()和skip()
限制查询条数
1、limit()方法:设置要显示的记录数
db.collection_name.find().limit(number)
2、skip()方法:设置要跳过的文档数
db.collection_name.find().skip(number)
十五、MongoDB排序
1、sort()方法:对查询到的文档进行排序
db.collection_name.find().sort({key:1})
其中key表示排序的字段,1表示升序排序,-1表示降序排序。
2、sort()方法未指定排序字段,则默认按_id升序排序。
十六、MongoDB索引
1、createIndex()方法:创建索引
db.collection_name.createIndex(keys,options)
keys:由键/值对组成,其中键用来定义要创建索引的字段,值用来定义创建索引的顺序,1表示按升序创建索引,-1表示按降序来创建索引。
options:可选参数,其中包含一组控制索引创建的选项
2、dropIndex()方法:删除指定的索引
db.collection_name.dropIndex(index)
index用来指定要删除的索引,可以是索引名称key的形式,也可以是{key:1}的形式。
3、dropIndexs()方法:同时删除集合中的多个索引,不需要提供任何参数。
4、getIndex()方法:获取集合中所有的索引,不需要提供任何参数。
十七、MongoDB聚合查询
1、MongoDB中的聚合操作用来处理数据并返回计算结果,聚合操作可以将多个文档的值组合在一起,并对数据执行各种操作,以返回单个结果。类似于SQL语句中的count(*)、group by等。
2、语法格式:
db.collection_name.aggregate(aggregate_operation)
例如:db.course.aggregate([{$group:{_id:"$author",sum:{$sum:1}}}]) 类似于SQL语句中的select author,count(*) from course group by author
3、聚合表达式:
表达式 | 描述 | 实例 |
---|---|---|
$sum | 计算总和 | db.mycol.aggregate([{$group:{id:"$author",num_tutorial:{$sum:"$likes"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{$group:{id:"$author",num_tutorial:{$avg:"$likes"}}}]) |
$min | 获取集合中所有文档对应值的最小值 | db.mycol.aggregate([{$group:{id:"$author",num_tutorial:{$min:"$likes"}}}]) |
$max | 获取集合中所有文档对应值的最大值 | db.mycol.aggregate([{$group:{id:"$author",num_tutorial:{$max:"$likes"}}}]) |
$push | 在结果文档中插入值到一个数组中 | db.mycol.aggregate([{$group:{id:"$author",url:{$push:"$url"}}}]) |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本 | db.mycol.aggregate([{$group:{id:"$author",url:{$addToSet:"$url"}}}]) |
$first | 根据资源文档的排序获取第一个文档数据 | db.mycol.aggregate([{$group:{id:"$author",first_url:{$first:"$url"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group:{id:"$author",last_url:{$last:"$url"}}}]) |
4、管道:在UNIX命令中,管道意味着可以将某些操作的输出结果作为下一个命令的参数,以此类推。MongoDB中同样也支持管道,即MongoDB会在一个管道处理完毕后将结果传递给下一个管道处理,而且管道操作是可以重复的。
5、聚合框架中常用的几个操作:
$project:用于从集合中选择要输出的字段;
$match:用于过滤数据,只输出符合条件的文档,可以减少作为下一阶段输入的文档数量;
$group:对集合中的文档进行分组,可用于统计结果;
$sort:将输入文档进行排序后输出;
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档;
$limit:用来限制MongoDB聚合管道返回的文档数量;
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
十八、MongoDB复制(副本集)
1、MongoDB中的复制就是跨多个服务器同步数据的过程,复制提供了数据的冗余备份,在多个服务器中存储数据副本,以此来提高数据的可用性,并可以保证数据的安全性。另外,复制还可以防止数据丢失,因为复制允许从硬件故障或服务中断的过程中恢复数据。
2、使用复制的好处:
确保数据的安全;
保障数据的高可用性;
数据恢复;
维护过程无需停机(例如备份、索引重建、压缩);
分布式读取数据;
副本集对应程序是透明的。
3、复制的工作方式:
MongoDB通过使用副本集来实现复制。副本集是一组托管相同数据集的MongoDB实例。在副本中,一个节点是接收所有写操作的主节点,其余的所有实例(例如第二实例)都将应用来自第一个实例的操作,以便它们具有相同的数据集。副本集只能有一个主节点。
特点:副本集是一组两个或更多节点(通常最少需要3个节点);
在副本集中,一个节点是主要节点,其余节点是从节点;
所有数据从主节点复制到从节点;
在自动故障转移或维护时,将为主节点建立选举,并选举一个新的主节点;
恢复失败的节点后,它再次加入副本集并用作辅助节点。
MongoDB复制示意图
4、副本集功能:
N个节点的集群;
任何一个节点都可以是主节点;
所有写操作都在主节点上;
自动故障转移;
自动恢复;
初选协商一致选举;
5、设置副本集:
5.1、关闭正在运行的MongoDB服务器;
5.2、通过指定 --replset选项启动MongoDB服务器,
--replset的基本语法:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replset "REPLICA_SET_INSTANCE_NAME"
5.3、示例:在27017端口上启动名为rso的mongod实例:
mongod --port 27017 --dbpath "D:\setup\mongodb\data" --replset rso
5.4、在MongoDB客户端中,使用rs.initiate()命令来启动新的副本集。使用rs.conf()命令检查副本集配置。使用rs.status()命令检查副本集的状态。
6、将成员添加到副本集
rs.add(HOST_NAME:PORT)
示例:将mongod实例名为mongod1.net添加到副本集
rs.add("mongod1.net:27017")
注意:仅当连接到主节点时,才能将mongod实例添加到副本集,使用db.isMaster()命令检查是否连到主服务器。
十九、MongoDB分片
1、为什么要分片:
1.1、在复制中,所有写操作都将转到主节点;
1.2、对延迟敏感的查询仍会转到主查询;
1.3、单个副本集限制为12个节点;
1.4、当活动数据集很大时,会出现内存不足;
1.5、本地磁盘不够大;
1.6、垂直扩展价格昂贵;
2、MongoDB中使用分片集群结构的分布
三个主要组件:
shards(碎片):用于存储实际的数据块,在生产环境中,每个分片都是一个单独的副本集,它们提供了高可用性和数据一致性;
Config Servers(配置服务器):用于存储集群的元数据,此数据包含集群数据集到碎片的映射,查询路由器使用此元数据将操作定向到特定的碎片。在生产环境中,分片群集恰好具有3个配置服务器。
Query Routers(查询路由器):查询路由器基本上都是mongo实例,可与客户端应用程序接口并将操作定向到适当的分片。查询路由器处理操作并将其定位到分片,然后将结果返回给客户端。
二十、数据备份
1、该命令可以导出所有数据到指定目录中,也可以通过参数将导出数据转存的服务器,语法格式如下:
mongodump -h dbhost -d dbname -o dbdirectory
参数说明如下:
-h:MongoDB所在服务器的地址,例如:127.0.0.1,同时也可以指定端口号,例如:127.0.0.1:27017;
-d:需要备份的数据库实例,例如:test;
-o:备份数据存放的位置,例如:c:/data/dump,该目录需要提前建立,在备份完成后,系统会自动在dump目录下建立一个test目录,并在这个目录里面存放该数据库实例的备份数据。
2、mongodump --host HOST_NAME --port PORT_NUMBER,该命令将备份所有MongoDB数据
mongodump --host runoob.com --port 27017
3、mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY,该命令将仅备份指定路径上的指定数据库
mongodump --dbpath /data/db/ --out /data/backup/
4、mongodump --colleciton COLLECTION --db DB_NAME,该命令将备份指定数据库的集合
mongodump --collection mycol --db test
二十一、恢复数据
1、该命令从备份目录还原所有数据:mongorestore
二十二、MongoDB监控运行状态
1、mongostart命令能够检查所有正在运行的mongod实例的状态,并返回数据库操作的计数器。这些计数器包括插入、查询、更新、删除和游标。当内存不足、写入量不足或者出现一些性能问题时,该命令还会显示发生错误的时间,并显示锁定百分比。
注意:要运行该命令,需要先启动mongod实例,并在另一个命令提示符(cmd)中转到MongoDB安装目录下的bin目录,最后输入mongostart命令并运行。
2、mongotop命令可以跟踪并报告MongoDB实例的读写活动。默认情况下,mongotop能够提供每个集合的水平统计数据,并每秒钟返回一次,也可根据需要对其进行修改。
修改返回信息频率:mongotop 20(表示20秒返回一次信息)
二十三、Java操作MongoDB
1、创建MongoDB连接
MongoClient mongo = new MongoClient("localhost",27017);
2、连接到MongDB
MongoCredential credential = MongoCredential.createCredential("sampleUser","myDb","123456".toCharArray());
3、访问数据库
MongoDatabase database = mongo.getDatabase("myDb");
4、创建集合
database.createCollection("tutorial");
5、检索集合
MongoCollection <Document> collection = database.getCollection("tutorial");
6、将文档插入到集合中
Document document = new Document("title","MongoDB")
.append("description","database")
.append("likes",100)
.append("url","http://www.biancheng.net/mongodb")
.append("by","编程帮");
collection.insertOne(document);
//将多个文档以列表形式插入集合中
Document document1 = new Document("title","Java")
.append("description","language")
.append("likes",200)
.append("url","Java学习教程,Java基础教程(从入门到精通)")
.append("by","编程帮");
Document document2 = new Document("title","Redis")
.append("description","NoSQL")
.append("likes",300)
.append("url","Redis数据库学习教程(快速入门版)")
.append("by","编程帮");
List<Document> list = new ArrayList<Document>();
list.add(document1);
list.add(document2);
collection.insertMany(list);
7、更新文档
collection.updateOne(Filters.eq("title","Java"),new Document("$set",new Document("like",150)));
8、查询文档
FindIterable<Document> iterDoc = colleciton.find();
Iterator iterator = iterDoc.iterator();
int i = 1;
while(iterator.hasNext()){
System.Out.PrintIn(iterator.next());
i++;
}
9、删除集合
collection.drop();
10、遍历集合
for(String collectionName:database.listCollectionNames()){
System.Out.PrintIn(collectionName);
}
二十四、MongDB关系:文档之间的关联
1、文档之间可以通过嵌入或引用来建立联系,联系种类:1:1(1对1)、1:N(1对多)、N:1(多对1)、N:N(多对多)。
2、嵌入式关系:将用户地址文档嵌入到用户文档中
3、引用式关系:用户地址文档和用户文档是分开的,通过引用文档的id字段来建立它们之间的关系。
二十五、MongDB的DBRefs:多表关联查询
1、DBRef的语法,形式如下:
{$ref:value,$id:value,$db:value}
$ref:此字段用来指定要引用文档所在的集合;
$id:此字段用来指定要引用文档的_id字段值;
$db:可选字段,用来指定要引用文档所在的数据库名称;
value:表示各个字段所对应得值。
二十六、MongDB覆盖索引查询
1、列索引是通过最大限度地减少查询所需的磁盘访问次数来优化查询性能的好方法。
2、覆盖查询是一下查询:查询中的所有字段都是索引的一部分;
查询中返回的所有字段都在同一索引中。
3、因为查询中的所有字段都索引的一部分,所以MongoDB匹配查询条件并使用相同的索引返回结果,而不实际查看文档内部。
4、由于索引存在于RAM中,从索引中获取数据比通过扫描文档文档获取数据快得多。
5、RAM(Random Access Memory):随机存取存储器,也叫主存,是与CPU直接交换数据的内部存储器。
6、如果是以下的查询,也不能使用覆盖索引查询:
所有索引字段是一个数组;
所有索引字段是一个子文档;
二十七、MongDB:$explain与$hint:查询分析
1、查询分析:衡量数据库和索引设计有效性的一个非常重要的方式。
2、$explain运算符提供了有关查询、索引使用以及查询统计的相关信息,在索引优化方面非常有用。
$explain的运行结果,有以下几点说明:
indexOnly:若字段的值为true,则表示此查询中使用了索引;
cursor:指定使用的游标类型,BTressCursor类型表示使用了索引,还提供了所用索引的名称,BasicCursor表示在不使用任何索引的情况下进行了完全扫描;
n:表示返回的匹配文档数;
nscannedObjects:表示扫描文档的总数;
nscanned:表示扫描的文档或索引条目的总数。
3、$hint运算符(也叫强制查询优化器)能够使用指定的索引来进行查询,以此来测试查询的性能,当想要测试具有不同索引的查询性能是,此功能特别有用。
二十八、MongDB原子操作
1、常用的原子操作命令:
1.1、$set:用来指定一个键并更新键值,若键不存在则创建。
{$set:{field:value}}
1.2、$unset:用来删除一个键
{$unset:{field:1}}
1.3、$inc:用来对文档的某个数值类型的键值进行增减操作
{$inc:{field:value}}
1.4、$push:用来向文档中追加一些信息
{$push:{field:value}}
把value追加到field里面去,field一定要是数组类型才行,如果field不存在,则会新增一个新数值类型加进去。
1.5、$pushAll:与$push类似,可以一次追加多个值到一个数组类型的字段内
{$pushAll:{field:value_array}}
1.6、$pull:从数组field内删除一个等于value的值
{$pull:{field:_value}}
1.7、$pop:删除数组的第一个或最后一个元素
{$pop:{field:}}
1.8、$rename:修改字段的名称
{$rename:{old_field_name:new_field_name}}
1.9、$bit:位操作,integer类型
{$bit:{field:{and:5}}}
二十九、MongoDB高级索引
1、索引数组字段:当在数组字段上创建索引时,MongoDB会自动在数组里的值的字段上也创建单独的索引。
2、索引子文档字段:在子文档里的所有字段上创建索引。
三十、MongoDB索引使用注意事项
1、额外开销:每个索引都会占用一些空间,并且在每次执行插入、更新和删除等操作时也需要对索引进行操作,导致额外的开销。因此,如果很少将某个集合用于读取操作,最好不要在集合中使用索引。
2、RAM使用:由于索引存储在RAM(内存)中,因此应确保索引的总大小不超过RAM的限制。如果总大小大于RAM的大小,那么MongoDB将删除一些索引,这就会导致性能下降。
3、查询限制:
在以下的查询中,不能使用索引:
正则表达式或否定运算符,例如:$nin、$not等;
算术运算符,例如:$mod等;
$where子句;
4、索引键限制:如果现有所有字段的值超过索引键的限制,那么MongoDB将不会创建索引。
5、插入超过索引键限制的文档:
如果文档索引字段的值超过了索引键的限制,那么MongoDB不会将任何文档插入到集合中。mongorestore和mongoimport实用程序也是如此。
6、最大范围:
在定义索引时有以下几点需要注意:
集合的索引不能超过64个;
索引名称的长度不能超过128个字符;
符合索引最多可以拥有31个字段;
三十一、MongoDB的ObjectId
1、ObjectId是一个12字节的BSON类型,具有以下结构:
前4个字节表示时间戳;
接下来的3个字节表示机器标识符;
紧接着的2个字节由进程id(PID)组成;
最后3个字节是一个随机计数器的值;
2、创建新的ObjectId:
newObjectId:ObjectId()======>ObjectId("6040966d8bafb29d166fe47")
3、创建文档的时间戳:
newObjectId.getTimestamp():获取文档的创建时间,使用ISO格式返回ObjectId中包含的时间。
4、将ObjectId转换为String
newObectId.str:返回Guid的字符串格式。
三十二、MongoDB的MapReduce
1、在用MongoDB查询时,若返回的数据量很大,或者做一些比较复杂的统计和聚合操作做花费的时间很长时,可以使用MongoDB中的mapReduce进行实现。mapReduce是个灵活且强大的数据聚合工具,它的好处是可以把一个聚合任务分解为多个小的任务,分配到多个服务器上并行处理。
2、MapReduce命令:
在mapReduce命令中要实现两个函数,分别是map函数和reduce函数,其中map函数调用emit(key,value),遍历集合中的所有记录,并将key与value传递给reduce函数进行处理,如下所示:
db.collection_name.mapReduce(
function(){emit(key,value);}, //map函数
function(key,values){return reduceFunction}, //reduce函数
{
out:collection,
query:document,
sort:document,
limit:number
}
)
参数说明如下:
map函数:一个javascript函数,它用一个键映射一个值并发出一个键值对;
reduce函数:一个javascript函数,用于减少或分组具有相同键的所有文档;
out:指定map-reduce查询结果的位置;
query:指定用于选择文档的可选选择条件;
sort:指定可选的排序条件;
limit:指定要返回的最大文档数(可选);
3、使用mapReduce命令选择集合中所有"status":"active"的文档,然后根据用户名对其进行分组,最后统计每个用户的发帖数量,代码如下:
db.posts.mapReduce(
function(){emit(this.user_name,1);},
function(key,value){return Array.sum(values)},
{
query{status:"active"},
out:"post_total"
}
)
输入出结果:
{
"result":"post_total",
"timeMillis":48,
"counts":{
"input":11,
"emit":11,
"reduce":2,
"output":2
}
"ok":1
}
运行结果,以下几点说明:
result:储存结果的collection的名字,是个临时集合,mapReduce的连接关闭后会被自动删除;
timeMillis:执行花费的时间,单位为毫秒;
input:满足条件被送到map函数的文档个数;
emit:在map函数emit被用的次数,也就是所有集合中的数据总量;
output:结果集合中的文档个数(count对调试非常有帮助);
ok:查询是否执行成功,成功为1;
err:若执行失败,则会在这里显示失败原因;
3、使用find方法,查看mapReduce查询的结果,结果为:
{"_id":"biancheng","value":5}
{"_id":"bianchengbang","value":6}
三十三、Mongodb全文检索
1、全文检索:对文本中的每个词建立索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户,整个过程类似于通过字典中的检索字表查字的过程。
三十四、MongoDB正则表达式
1、使用$regex操作符来设置匹配字符串的正则表达式,使用PCRE(perl兼容的正则表达式)作为正则表达式语言。
2、不区分大小写的情况下使用正则表达式:$options:"$i"。
三十五、MongoDB管理工具RockMongo
1、RockMongo是一个MongoDB管理工具,可以使用它来管理MongoDB服务、数据库、集合、文档、索引。
三十六、MongoDB的GridFS
1、GridFS是MongoDB的一种规范,用于存储和检索大型文件,如图像、音频、视频,也是一种存储文件的文件系统,但其数据是存储在MongoDB集合中的,GridFS甚至可以存储超过16MB的文件。在存储文件时GridFS可以将一个文件分为多个数据块,并将每个数据块存储在一个单独的文档中,每个文档最大为255kb。
2、默认情况下,GridFS使用fs.files和fs.chunks两个集合来存储文件的元数据和块。每个区块都由其唯一的ObjectId(_id)字段标识,fs.files用作父文档,fs.chunks文档中的file_id字段将块链接到其父级。
3、将文件添加到GridFS:
mongofiles.exe -d gridfs(存储文件的数据库名称,若不存在,则自动创建) put F:/code/music/song.mp3(存储文件的路径以及名称)
三十七、MongoDB固定集合(Capped Collections)
1、db.createCollection("bianchengbang",{capped:true,size:1000,max:1000})
capped:true表示固定大小集合
size:1000表示集合大小(单位:字节)
max:1000表示文档最大数量
2、检查集合是否为固定集合:
db.bianchengbang.isCapped()
返回true表示是固定集合,false表示不是固定集合。
3、将已存在集合转为固定集合:
db.runCommand({"convertToCapped":"bianchengbang",size:1000})
返回{"ok":1}
4、固定集合查询:文档是按插入顺序储存,默认情况下,查询也是按插入顺序返回,可以使用sort()方法调整返回顺序,例如:db.bianchengbang.find().sort({$natural:-1})
5、关于固定集合,有以下几点需要注意:
5.1、可以在固定集合中插入或更新数据,但是更新时数据不能超出集合的大小,否则更新失败;
5.2、不允许删除固定集合中的文档,但是可以使用drop()方法删除集合中的所有数据,在drop后需要显式重建集合;
5.3、固定集合不存在默认索引,甚至_id字段上也不存在;
5.4、在插入新文档时,MongoDB实际上不必再磁盘上寻找容纳新文档的位置,它可以在集合的尾部盲目地插入新文档,这使得在固定集合中插入文档非常快;
5.5、在查询文档时,MongoDB返回的文档顺序与文档在磁盘上存储的顺序相同的,这使得查询文档的速度非常快。