您现在的位置是:首页 >学无止境 >MongoDB 基本介绍和操作网站首页学无止境

MongoDB 基本介绍和操作

和你一起去月球 2024-08-31 12:01:03
简介MongoDB 基本介绍和操作

目录

1、mongodb 简介

 2、mongodb 概念解析

3、mongodb 连接

4、mongodb 数据库操作

5、mongodb 文档操作

6、mongodb 条件操作符

7、mongodb Limit与Skip 方法

8、mongodb 排序

9、mongodb 索引

10、mongodb 聚合

11、mongodb 复制(副本集)

12、mongodb 分片

13、mongodb 备份与恢复

14、mongodb 监控

15、mongodb 查询分析

16、mongodb 原子操作

17、mongodb ObjecctId

18、MongoDB Map Reduce

19、mongodb 正则表达式

20、MongoDB GridFS


1、mongodb 简介

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。
MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

 2、mongodb 概念解析

SQL术语/概念               MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins- 表连接,MongoDB不支持
primary key   primary key   主键,MongoDB自动将_id字段设置为主键

数据库

一个mongodb中可以建立多个数据库。
MongoDB的默认数据库为"db",该数据库存储在data目录中。
MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,
不同的数据库也放置在不同的文件中。

文档
文档是一个键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,
并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,
也是 MongoDB 非常突出的特点。

3、mongodb 连接

使用用户名和密码连接到MongoDB服务器,你必须使用 'username:password@hostname/dbname' 格式,'username'为用户名,'password' 为密码。


例如
使用用户名fred,密码foobar登录localhost的admin数据库。
mongodb://fred:foobar@localhost

连接 replica pair, 服务器1为example1.com服务器2为example2。
mongodb://example1.com:27017,example2.com:27017

4、mongodb 数据库操作

MongoDB 创建数据库的语法格式如下:

use DATABASE_NAME

如果数据库不存在,则创建数据库,否则切换到指定数据库。

查看所有数据库,可以使用 show dbs 命令。

MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。

MongoDB 删除数据库的语法格式如下:

db.dropDatabase()

删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。

MongoDB删除集合 语法格式如下:

db.collection.drop()

5、mongodb 文档操作

MongoDB 使用 insert() 或 save() 方法向集合中 插入文档,语法如下:
  
db.COLLECTION_NAME.insert(document)

实例:
 
db.col.insert(
{title: 'MongoDB 教程',
    description: 'MongoDB 是一个 Nosql 数据库',
    by: 'test',
    url: 'https://www.baidu.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
}
)

查看插入的文档

db.col.find()
mongodb 更新文档 - update
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 :可选,抛出异常的级别。
mongodb 更新文档 - save
save() 方法通过传入的文档来替换已有文档。语法格式如下:
db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)
参数说明:
document : 文档数据。
writeConcern :可选,抛出异常的级别。

实例:
>db.col.save({
 "_id" : ObjectId("56064f89ade2f21f36b03136"),
    "title" : "MongoDB",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "Runoob",
    "url" : "http://www.runoob.com",
    "tags" : [
            "mongodb",
            "NoSQL"
    ],
    "likes" : 110
})
mongodb 删除文档 - remove
remove() 方法的基本语法格式如下所示:
db.collection.remove(
   <query>,
   <justOne>
)

参数说明:
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档。
writeConcern :(可选)抛出异常的级别。

实例:
db.col.remove({'title':'MongoDB 教程'})
WriteResult({ "nRemoved" : 2 })      # 删除了两条数据
db.col.find()                                                   …… # 没有数据
mongodb 查询文档 - find
MongoDB 查询数据的语法格式如下:

db.COLLECTION_NAME.find()

如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:

db.col.find().pretty()

MongoDB 与 RDBMS Where 语句比较
操作                             格式  范例        RDBMS中的类似语句
等于 {<key>:<value>}db.col.find({"by":"菜鸟教程"}).pretty() where by = 'test'
小于  {<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

6、mongodb 条件操作符

MongoDB中条件操作符有:

(>) 大于 - $gt                                         (<) 小于 - $lt
(>=) 大于等于 - $gte                          (<= ) 小于等于 - $lte

AND 和 OR 联合使用
类似常规 SQL 语句为: 'where likes>50 AND (by = '菜鸟教程' OR title = 'MongoDB 教程')'
db.col.find({"likes": {$gt:50}, $or: [{"by": "test"},{"title": "MongoDB 教程"}]}).pretty()
{
        "_id" : ObjectId("ksdfj11283012381023"),
        "title" : "MongoDB 教程",
        "description" : "MongoDB 是一个 Nosql 数据库",
        "by" : "test",
        "url" : "https://www.baidu.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}

7、mongodb Limit与Skip 方法

limit()方法基本语法如下所示:

db.COLLECTION_NAME.find().limit(NUMBER)

实例:

db.col.find({},{"title":1,_id:0}).limit(2)

{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }


skip() 方法脚本语法格式如下:
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

实例:

db.col.find({},{"title":1,_id:0}).limit(1).skip(1)

{ "title" : "Java 教程" }

8、mongodb 排序

MongoDB sort()方法

在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的
字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。

语法
  

sort()方法基本语法如下所示:
db.COLLECTION_NAME.find().sort({KEY:1})

9、mongodb 索引

MongoDB使用 ensureIndex() 方法来创建索引。
语法  
ensureIndex()方法基本语法格式如下所示:  
db.COLLECTION_NAME.ensureIndex({KEY:1})

实例:
ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
db.col.ensureIndex({"title":1,"description":-1})
ensureIndex() 接收可选参数,可选参数列表如下:

参数类型描述
backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDupsBoolean3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

10、mongodb 聚合

aggregate() 方法的基本语法格式如下所示:

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

表达式描述实例
$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"}}}])

管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。
管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,
不能处理其它的文档。

这里我们介绍一下聚合框架中常用的几个操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,
                        也可以用于创建计算结果以及嵌套文档。
  
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  
$limit:用来限制MongoDB聚合管道返回的文档数。

$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。

$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

$group:将集合中的文档分组,可用于统计结果。

$sort:将输入文档排序后输出。

$geoNear:输出接近某一地理位置的有序文档。

11、mongodb 复制(副本集)

MongoDB复制原理

mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是

从节点,负责复制主节点上的数据。

mongodb各个节点常见的搭配方式为:一主一从、一主多从。

主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据

                副本执行这些操作,从而保证从节点的数据与主节点一致。

MongoDB复制结构图如下所示:

MongoDB副本集设置

1、关闭正在运行的MongoDB服务器。

现在我们通过指定 --replSet 选项来启动mongoDB。--replSet 基本语法格式如下:

mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet

 "REPLICA_SET_INSTANCE_NAME"

实例

mongod --port 27017 --dbpath "D:set upmongodbdata" --replSet rs0

以上实例会启动一个名为rs0的MongoDB实例,其端口号为27017。

副本集添加成员

rs.add(HOST_NAME:PORT)

实例

rs.add("mongod1.net:27017")

12、mongodb 分片

分片

在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。

当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的

读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理

更多的数据。

为什么使用分片

(1)复制所有的写入操作到主节点

(2)延迟的敏感数据会在主节点查询

(3)单个副本集限制在12个节点

(4)当请求量巨大时会出现内存不足。

(5)本地磁盘不足

(6)垂直扩展价格昂贵

 
MongoDB分片

 

 上图中主要有如下所述三个主要组件:
Shard:
     用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个
     relica set     承担,防止主机单点故障
Config Server:
      mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
Query Routers:
     前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

分片实例
分片结构端口分布如下:
Shard Server 1:27020
Shard Server 2:27021
Config Server :27100
Route Process:40000

步骤一:启动Shard Server
[root@100 /]# mkdir -p /www/mongoDB/shard/s0
[root@100 /]# mkdir -p /www/mongoDB/shard/s1
[root@100 /]# mkdir -p /www/mongoDB/shard/log
[root@100 /]# /usr/local/mongoDB/bin/mongod --port 27020 --dbpath=
                                 /www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log
                                --logappend --fork

步骤二: 启动Config Server
[root@100 /]# mkdir -p /www/mongoDB/shard/config
[root@100 /]# /usr/local/mongoDB/bin/mongod --port 27100 --dbpath=
                                /www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log
                                --logappend --fork

步骤三: 启动Route Process
                      /usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork
                      --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500

步骤四: 配置Sharding

接下来,我们使用MongoDB Shell登录到mongos,添加Shard节点

[root@100 shard]# /usr/local/mongoDB/bin/mongo admin --port 40000
MongoDB shell version: 2.0.7
connecting to: 127.0.0.1:40000/admin
mongos> db.runCommand({ addshard:"localhost:27020" })
{ "shardAdded" : "shard0000", "ok" : 1 }
......
mongos> db.runCommand({ addshard:"localhost:27029" })
{ "shardAdded" : "shard0009", "ok" : 1 }
mongos> db.runCommand({ enablesharding:"test" }) #设置分片存储的数据库
{ "ok" : 1 }
mongos> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}})
{ "collectionsharded" : "test.log", "ok" : 1 }

步骤五: 程序代码内无需太大更改,直接按照连接普通的mongo数据库那样,

将数据库连接接入接口40000

13、mongodb 备份与恢复

语法
mongodump命令脚本语法如下:
>mongodump -h dbhost -d dbname -o dbdirectory

-h:
MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017

-d:
需要备份的数据库实例,例如:test

-o:
备份的数据存放位置,例如:c:datadump,当然该目录需要提前建立,在备份完成后,

系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。

mongodump 命令可选参数列表如下所示:
语法描述实例
mongodump --host HOST_NAME --port PORT_NUMBER该命令将备份所有MongoDB数据mongodump --host runoob.com --port 27017
mongodump --dbpath DB_PATH --out BACKUP_DIRECTORYmongodump --dbpath /data/db/ --out /data/backup/
mongodump --collection COLLECTION --db DB_NAME该命令将备份指定数据库的集合。mongodump --collection mycol --db test

MongoDB数据恢复

mongodb使用 mongorerstore 命令来恢复备份的数据。

语法
mongorestore命令脚本语法如下:
>mongorestore -h dbhost -d dbname --directoryperdb dbdirectory

-h:
MongoDB所在服务器地址

-d:
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
  
--directoryperdb:
备份数据所在位置,例如:c:datadump est,这里为什么要多加一个test,

而不是备份时候的dump,读者自己查看提示吧!

--drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,

备份后添加修改的数据都会被删除,慎用哦!

14、mongodb 监控

mongostat 命令

它会间隔固定时间 获取mongodb的当前运行状态,并输出

启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongostat

命令,如下所示:

D:set upmongodbin>mongostat

mongotop命令

用来跟踪一个MongoDB的实例,查看哪些大量的时间花费在 读取和写入数据。

 mongotop提供每个集合的水平的统计数据
。默认情况下,mongotop返回值的每一秒。

如下所示:

D:set upmongodbin>mongotop

15、mongodb 查询分析

使用 explain()

explain 操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。
  
接下来我们在 users 集合中创建 gender 和 user_name 的索引:

db.users.ensureIndex({gender:1,user_name:1})

db.users.find({gender:"M"},{user_name:1,_id:0}).explain()

查看返回结果集的字段:
indexOnly: 字段为 true ,表示我们使用了索引。
cursor:因为这个查询使用了索引,MongoDB中索引存储在B树结构中,所以这是也使用了
                    BtreeCursor类型的游标。如果没有使用索引,游标的类型是BasicCursor。这个键
                   还会给出你所使用的索引的名称,你通过这个名称可以查看当前数据库下的
                   system.indexes集合(系统自动创建,由于存储索引信息,这个稍微会提到)来得到
                  索引的详细信息。
n:当前查询返回的文档数量。
nscanned/nscannedObjects:表明当前这次查询一共扫描了集合中多少个文档,我们的目的是让这个数值和返回文档的数量越接近越好。
millis:当前查询所需时间,毫秒数。
indexBounds:当前查询具体使用的索引。

使用 hint()

虽然MongoDB查询优化器一般工作的很不错,但是也可以使用hints来强迫MongoDB使用

一个指定的索引。


这种方法某些情形下会提升性能。 一个有索引的collection并且执行一个多字段的查询

(一些字段已经索引了)。

如下查询实例指定了使用 gender 和 user_name 索引字段来查询:

db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})

可以使用 explain() 函数来分析以上查询:

db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()

16、mongodb 原子操作

所谓原子操作就是要么这个文档保存到Mongodb,要么没有保存到Mongodb,不会出现查
询到的文档没有保存完整的情况。
比如文档的保存,修改,删除等,都是原子操作。
$set
         用来指定一个键并更新键值,若键不存在并创建。
          { $set : { field : value } }
$unset
        用来删除一个键。
        { $unset : { field : 1} }
$inc
         $inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
         { $inc : { field : value } }
$push用法
         { $push : { field : value } }
$pushAll
        同$push,只是一次可以追加多个值到一个数组字段内。
        { $pushAll : { field : value_array } }
$pull
       从数组field内删除一个等于value值。
       { $pull : { field : _value } }
$addToSet
增加一个值到数组内,而且只有当这个值不在数组内才增加。

$pop
删除数组的第一个或最后一个元素
{ $pop : { field : 1 } }

$rename
修改字段名称
{ $rename : { old_field_name : new_field_name } }

$bit
位操作,integer类型

{$bit : { field : {and : 5}}}

偏移操作符

> t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" :
[ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }
 
> t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )
 
> t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" :
[ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }

17、mongodb ObjecctId

ObjectId 是一个12字节 BSON 类型数据,有以下格式:
  
(1)前4个字节表示时间戳
(2)接下来的3个字节是机器标识码
(3)紧接的两个字节由进程id组成(PID)
(4)最后三个字节是随机数。

创建新的ObjectId
使用以下代码生成新的ObjectId:
           newObjectId = ObjectId()
上面的语句返回以下唯一生成的id:
          ObjectId("5349b4ddd2781d08c09890f3")

创建文档的时间戳
由于 ObjectId 中存储了 4 个字节的时间戳,所以你不需要为你的文档保存时间戳字段,
你可以通过 getTimestamp 函数来获取文档的创建时间:
          ObjectId("5349b4ddd2781d08c09890f4").getTimestamp()

ObjectId 转换为字符串
在某些情况下,您可能需要将ObjectId转换为字符串格式。你可以使用下面的代码:
          new ObjectId().str
以上代码将返回Guid格式的字符串:                    5349b4ddd2781d08c09890f3

18、MongoDB Map Reduce

Map-Reduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,
                             然后再将结果合并成最终结果(REDUCE)。
MongoDB提供的Map-Reduce非常灵活,对于大规模数据分析也相当实用。
以下是MapReduce的基本语法:
>db.collection.mapReduce(
   function() {emit(key,value);}, //map 函数
   function(key,values) {return reduceFunction}, //reduce 函数
   {
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)

map :映射函数 (生成键值对序列,作为 reduce 函数参数)。
reduce 统计函数,reduce函数的任务就是将key-values变成key-value,也就是把values数组
                 变成一个单一的值value。。
out      统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
query   一个筛选条件,只有满足条件的文档才会调用map函数。
        (query。limit,sort可以随意组合)
sort 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
limit 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)

计算每个用户的文章数:
  
>db.posts.mapReduce(
   function() { emit(this.user_name,1); },
   function(key, values) {return Array.sum(values)},
      {
         query:{status:"active"},
         out:"post_total"
      }
)

以上 mapReduce 输出结果为:
{
        "result" : "post_total",
        "timeMillis" : 23,
        "counts" : {
                "input" : 5,
                "emit" : 5,
                "reduce" : 1,
                "output" : 2
        },
        "ok" : 1
}
结果表明,共有4个符合查询条件(status:"active")的文档, 在map函数中生成了4个键值对

文档,最后使用reduce函数将相同的键值分为两组。

具体参数说明:

result:储存结果的collection的名字,这是个临时集合,MapReduce的连接关闭后自动就被删除了。
   
timeMillis:执行花费的时间,毫秒为单位

input:满足条件被发送到map函数的文档个数

emit:在map函数中emit被调用的次数,也就是所有集合中的数据总量

ouput:结果集合中的文档个数(count对调试非常有帮助)

ok:是否成功,成功为1

err:如果失败,这里可以有失败原因,不过从经验上来看,原因比较模糊,作用不大

19、mongodb 正则表达式

MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。

以下命令使用正则表达式查找包含 w3cschool.cc 字符串的文章:
      db.posts.find({post_text:{$regex:"w3cschool.cc"}})

以上查询也可以写为:
>db.posts.find({post_text:/w3cschool.cc/})

不区分大小写的正则表达式 ,我们可以设置 $options 为 $i。

   db.posts.find({post_text:{$regex:"w3cschool.cc",$options:"$i"}})

{
   "_id" : ObjectId("53493d37d852429c10000004"),
   "post_text" : "hey! this is my post on W3Cschool.cc",
   "tags" : [ "tutorialspoint" ]


数组元素使用正则表达式
如果你需要查找包含以 tutorial 开头的标签数据(tutorial 或 tutorials 或 tutorialpoint 或
 tutorialphp), 你可以使用以下代码:
>db.posts.find({tags:{$regex:"tutorial"}})

优化正则表达式查询

如果你的文档中字段设置了索引,那么使用索引相比于正则表达式匹配查找所有的数据查

询速度更快。

如果正则表达式是前缀表达式,所有匹配的数据将以指定的前缀字符串为开始。

例如: 如果正则表达式为 ^tut ,查询语句将查找以 tut 为开头的字符串。

这里面使用正则表达式有两点需要注意

正则表达式中使用变量。一定要使用eval将组合的字符串进行转换,不能直接将字符串拼接

后传入给表达式。否则没有报错信息,只是结果为空!实例如下:

var name=eval("/" + 变量值key +"/i");

以下是模糊查询包含title关键词, 且不区分大小写:

title:eval("/"+title+"/i") // 等同于 title:{$regex:title,$Option:"$i"}   

20、MongoDB GridFS

GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等)。
GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中。
GridFS 可以更好的存储大于16M的文件。
GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为
MongoDB的一个文档(document)被存储在chunks集合中。
GridFS 用两个集合来存储一个文件:fs.files与fs.chunks。
每个文件的实际内容被存在chunks(二进制数据)中,和文件有关的meta数据
(filename,content_type,还有用户自定义的属性)将会被存在files集合中。
以下是简单的 fs.files 集合文档:
{
   "filename": "test.txt",
   "chunkSize": NumberInt(261120),
   "uploadDate": ISODate("2014-04-13T11:32:33.557Z"),
   "md5": "7b762939321e146569b07f72c62cca4f",
   "length": NumberInt(646)
}
以下是简单的 fs.chunks 集合文档:
{
   "files_id": ObjectId("534a75d19f54bfec8a2fe44b"),
   "n": NumberInt(0),
   "data": "Mongo Binary Data"
}

GridFS 添加文件
现在我们使用 GridFS 的 put 命令来存储 mp3 文件。 调用 MongoDB 安装目录下bin的 mongofiles.exe工具。
打开命令提示符,进入到MongoDB的安装目录的bin目录中,找到mongofiles.exe,并输入下面的代码:
>mongofiles.exe -d gridfs put song.mp3
GridFS 是存储文件的数据名称。如果不存在该数据库,MongoDB会自动创建。Song.mp3 是音频文件名。
使用以下命令来查看数据库中文件的文档:
>db.fs.files.find()
以上命令执行后返回以下文档数据:
{
   _id: ObjectId('534a811bf8b4aa4d33fdf94d'),
   filename: "song.mp3",
   chunkSize: 261120,
   uploadDate: new Date(1397391643474), md5: "e4f53379c909f7bed2e9d631e15c1c41",
   length: 10401959
}
我们可以看到 fs.chunks 集合中所有的区块,以下我们得到了文件的 _id 值,我们可以根据这个 _id 获取区块(chunk)的数据:
>db.fs.chunks.find({files_id:ObjectId('534a811bf8b4aa4d33fdf94d')})
以上实例中,查询返回了 40 个文档的数据,意味着mp3文件被存储在40个区块中。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。