MongoDB

  • 一、MongoDB特点
    • 1、MongoDB优点
    • 2、MongoDB缺点
  • 二、MongoDB数据结构
  • 三、 数据库
  • 四、集合
  • 五、文档
  • 六、搭建复制集

一、MongoDB特点

1、MongoDB优点

1、面向文档结构(集合)的存储方式,容易存储对象类型的数据,操作简单
2、内置GridFS,支持大容量的存储
3、内置sharding分片技术,当负载超核(超出存储空间和处理能力时),可以分布在网络中其他节点上(简单点一台不行,可以两台处理.....再加)
4、海量数据下,性能优越
5、支持自动故障恢复Colleca Set(复制集)
6、自动处理碎片,以支持云计算层次的扩展性
7、支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。
8、文件存储格式为BSON(一种JSON的扩展,可轻易查询文档中内嵌的对象及数组)
9、支持动态查询
10、支持查询
11、支持完全索引
12、Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作

2、MongoDB缺点

1、不支持事务操作
2、占用空间过大
3、MongoDB没有如MySQL那样成熟的维护工具
4、无法进行关联表查询,不适用于关系多的数据
5、复杂聚合操作通过mapreduce创建,速度慢
6.模式自由,  自由灵活的文件存储格式带来的数据错误
7、预分配模式带来的磁盘瓶颈
8、在数据存量大于内存大小时,mongodb遇到冷数据查询速度变慢
9、Mongodb全局锁机制
10、删除数据集合后空间不会自动释放

扩展:
1、reduce() 函数会对参数序列中元素进行累积

def f(x, y):return x + y
reduce(f, [1, 3, 5, 7, 9])  # 返回结果为25
# reduce()还可以接收第3个可选参数,作为计算的初始值
# 如果把初始值设置为100
reduce(f, [1, 3, 5, 7, 9], 100) # 返回结果为125

2、GridFS
GridFS使用两个集合保存数据,一个集合存储文件块,另外一个存储文件元数据,一种将大型文件存储在MongoDB的文件规范,所有官方支持的驱动均实现了GridFS规范。GridFS制定大文件在数据库中如何处理,通过开发语言驱动来完成、通过API接口来存储检索大文件

二、MongoDB数据结构

在这里插入代码片

三、 数据库

> show dbs    # 查看所有的数据库
admin     0.000GB
config    0.000GB
local     0.000GB
runoobdb  0.000GB
test      0.000GB
> use runoobdb     # 切换到指定的数据库,如果不存在就创建该数据库
switched to db runoobdb
> db     # 查看当前数据库
runoobdb
> db.dropDatabase()  # 删除当前数据库
{ "dropped" : "runoobdb", "ok" : 1 }
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

四、集合

创建集合语法:db.createCollection(name, options)
参数解释:name: 要创建的集合名称options: 可选参数, 指定有关内存大小及索引的选项

options 可以是如下参数:

字段 类型 描述
capped 布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
autoIndexId 布尔 3.2 之后不再支持该参数。(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
size 数值 (可选)为固定集合指定一个最大值,即字节数。如果 capped 为 true,也需要指定该字段。
max 数值 (可选)指定固定集合中包含文档的最大数量。在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。
1、创建集合 方法1
> db.createCollection('robys')   # 创建集合robys
{ "ok" : 1 }
# 方法2:向xxx集合中插入文档时,如果该集合不存在,MongoDB会自动创建该集合的
> db.mycol.insert({'name':'jacky','age':19,'job':'python开发工程师'})
WriteResult({ "nInserted" : 1 })2、查看当前数据库中的所有集合
> show collections
robys
mycol
#方法2:查看集合
> show tables          # 查看当前数据库中所有集合(方法2)
mycol
robys3、删除当前数据库中某集合
> show collections
mycol
names
robys
> db.mycol.drop()  # 删除集合mycol
true
> show collections
names
robys

五、文档

1、插入单个文档
# 语法:db.collection.insertOne(<document>,{writeConcern: <document>})
> db.names.insertOne({'name':'jacky'})
{"acknowledged" : true,"insertedId" : ObjectId("604c9008dda7813ccf9d257c")
}
> db.names.find().pretty()
{ "_id" : ObjectId("604c9008dda7813ccf9d257c"), "name" : "jacky" }2、插入多个文档,并按顺序写入
# 语法:db.collection.insertMany([<document 1>,<document 2>, ... ],{writeConcern:<document>,ordered: <boolean>})
> db.robys.insertMany([{'name':'chen1',"age":13},{"name":"jewow","job":"student"}],{orderd:-1})
{"acknowledged" : true,"insertedIds" : [ObjectId("604c9b25dda7813ccf9d257e"),ObjectId("604c9b25dda7813ccf9d257f")]
}
> db.robys.find().pretty()
{"_id" : ObjectId("604c9b25dda7813ccf9d257e"),"name" : "chen1","age" : 13
}
{"_id" : ObjectId("604c9b25dda7813ccf9d257f"),"name" : "jewow","job" : "student"
}
# 方法2:插入文档
> document=({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库',by: '菜鸟教程',url: 'http://www.runoob.com',tags: ['mongodb', 'database', 'NoSQL'],likes: 100
})
> db.col.insert(document)  # insert如果文档的‘_id ’主键存在,则会抛 org.springframework.dao.DuplicateKeyException 异常
WriteResult({ "nInserted" : 1 })3、更新档方法1: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.names.update({'name':'jacky'},{$set:{"say":"erwerwer3223423"}},{multi:true})  # $set不存在就添加
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.names.find().pretty()
{"_id" : ObjectId("604c9008dda7813ccf9d257c"),"name" : "jacky","say" : "erwerwer3223423"
}4、更新档方法2:save() 方法
# 语法:save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入。语法格式如下:
# db.collection.save(<document>,{writeConcern: <document>})
> db.names.find().pretty()
{"_id" : ObjectId("604c9008dda7813ccf9d257c"),"name" : "jacky","say" : "erwerwer3223423"
}
> db.names.save({"_id" : ObjectId("604c9008dda7813ccf9d257c"),"name" : "33333333","say" : "我是save更新的"})    # save()用法
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.names.find().pretty()
{                     "_id" : ObjectId("604c9008dda7813ccf9d257c"),"name" : "33333333","say" : "我是save更新的"
}5、删除文档
# 语法:db.collection.remove(<query>,{justOne: <boolean>,writeConcern: <document>})
#      db.collection.remove(<query>,<justOne>)
> db.robys.find()
{ "_id" : ObjectId("604c9b25dda7813ccf9d257e"), "name" : "chen1", "age" : 13 }
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "jewow", "job" : "student" }
> db.robys.remove({"name":"chen1"},{justOne:true})  # 删除name=chen1的记录,justOne=true表示只删除匹配的第一个,justOne=false表示删除所有匹配的到记录
WriteResult({ "nRemoved" : 1 })
> db.robys.find()
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "jewow", "job" : "student" }6、通过比较操作符查询文档
# 语法:db.collection.find(query, projection)
# query条件查询操作符:
# gt gte lt  lte ne
> db.robys.find()
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 20}
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "王五", "age" : 30}
# 1、{"key":"value"} --> 匹配值等于value的文档
> db.robys.find({"age":14})   # age = 14
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
# 2、gt --> 匹配值大于value的文档
> db.robys.find({"age":{$gt:19}})  # age > 19
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 20}
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "王五", "age" : 30}
# 3、gte --> 匹配值大于等于value的文档
> db.robys.find({"age":{$gte:30}})  # age >= 30
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "王五", "age" : 30}
# 4、lt --> 匹配值小于value的文档
> db.robys.find({"age":{$lt:21}})  # age < 21
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 20}
# 5、lte --> 匹配值小于等于value的文档
> db.robys.find({"age":{$lte:14}})  # age <= 14
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
# 6、ne --> 匹配值不等于value的文档
> db.robys.find({"age":{$ne:14}})  # age != 14
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 20}
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "王五", "age" : 30}7、通过逻辑操作符查找文档(and or )
> db.robys.find()
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 19}
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 20}
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 14}
#  条件查询  ----and
>db.robys.find({"name":"张三","age":"14"})  # name=张三 and age=14
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
#  条件查询  ----or
>db.robys.find({$or:{"name":"张三","age":"14"}})  # name=张三 or age=14 或者同时满足
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 19}
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 14}
8、通过类型操作符操作文档
>db.robys.find({"name":{"$type":"string"}})
>db.robys.find({"name":{"$type":"2"}})
>db.robys.find({"age":{"$type":"32-bit integer"}})
>db.robys.find({"age":{"$type":"16"}})
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三", "age" : 14}
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : 20}
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "name" : "王五", "age" : 30}

MongoDB 中可以使用的类型如下表所示:

类型 数字 备注
Double 1 双精度浮点值。用于存储浮点值
String 2 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的
Object 3 用于内嵌文档
Array 4 用于将数组或列表或多个值存储为一个键
Binary data 5 二进制数据。用于存储二进制数据
Undefined 6 已废弃。
Object id 7 对象 ID。用于创建文档的 ID。  (每个文档都有)
Boolean 8 布尔值。用于存储布尔值(真/假)
Date 9 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息
Null 10 用于创建空值
Regular Expression 11 此数据类型用于存储正则表达式
JavaScript 13 代码类型。用于在文档中存储 JavaScript 代码
Symbol 14 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
JavaScript (with scope) 15
32-bit integer 16 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位
64-bit integer 18 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位
Timestamp 17 时间戳。记录文档修改或添加的具体时间
Min key 255 Query with -1. ,将一个值与 BSON(二进制的 JSON)元素的最低值相对比
Max key 127 将一个值与 BSON(二进制的 JSON)元素的最高值相对比

扩展:db.collection.update()更新时不带$set的区别:

> db.robys.find()
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "age" : 20 }
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : "30", "job" : "工程师" }
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "name" : "张三" }
> db.robys.update({"name":"张三"},{"age":14},{upsert:true})  # 直接用新文档替换了
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.robys.find()
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "age" : 20 }
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : "30", "job" : "工程师" }
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "age" : 14 }
> db.robys.update({"age":14},{$set:{"name":"张三"}},{upsert:true})  # 加$set:只是在原有的基础上添加新的字段
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.robys.find()
{ "_id" : ObjectId("604c9b25dda7813ccf9d257f"), "age" : 20 }
{ "_id" : ObjectId("604cdba376c1c3f0855f5447"), "name" : "李四", "age" : "30", "job" : "工程师" }
{ "_id" : ObjectId("604cdc492a6750e575c88829"), "age" : 14, "name" : "张三" }

六、搭建复制集

1.安装mongdb
2.初始化数据库
> mongod --dbpath D:\mongdb_data\mongodb\data\db
3.创建配置文件mongod.conf

 systemLog:destination: filepath: D:\mongdb_data\mongodb\log\mongod.log logAppend: truestorage:  dbPath: D:\mongdb_data\mongodb\data\dbjournal: enabled: true replication: replSetName: rs

4.windows7上注册服务
> mongod.exe --config "D:\mongdb_data\mongdb_01\mongod.conf" --dbpath "D:\mongdb_data\mongdb_01\db" --install
测试服务是否成功:
net start MongoDB
net stop MongoDB# 测试完记得一定要stop
5.同一台计算机上实验,所以创建两个节点
mongod --port 27018 --dbpath "D:\mongdb_data\mongdb_02\db" --replSet rs# 这两个窗口不要关闭
mongod --port 27019 --dbpath "D:\mongdb_data\mongdb_03\db" --replSet rs# 这两个窗口不要关闭
6.重新打开cmd,开启服务,连接mongodb
net start MongoDB
mongo#添加了环境变量,具体命令:C:\tools\mongdb\bin\mongo.exe
7.初始化复制集
rs.initiate()
8.复制集添加成员
rs.add("127.0.0.1:27018")
rs.add("127.0.0.1:27019")
re.config()# 查看复制集的配置
rs.status()# 查看副本集状态
db.isMaster()# 判断当前运行的Mongo服务是否为主节点
rs.stepDown()# 主节点退位
db.isMaster()# 检查是否是主节点
rs.remove("10.1.8.69:27018")# 移除节点
rs.slaveOk()# 在Secondary节点上执行rs.slaveOk()后,就可以执行其他命令,否则Secondary节点不允许执行其他命令(如:show dbs)
9.强制关闭主节点上的MongoDB服务
use admin
db.shutdownServer()

扩展: 复制集中添加节点
节点分类:
Primary节点:复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消息,并发起Priamry选举操作,获得『大多数』成员投票支持的节点,会成为Primary,其余节点成为Secondary。
  Secondary节点:正常情况下,复制集的Seconary会参与Primary选举(自身也可能会被选为Primary),并从Primary同步最新写入的数据,以保证与Primary存储相同的数据。Secondary可以提供读服务,增加Secondary节点可以提供复制集的读服务能力,同时提升复制集的可用性。另外,Mongodb支持对复制集的Secondary节点进行灵活的配置,以适应多种场景的需求。
  Arbiter节点:Arbiter节点只参与投票,不能被选为Primary,并且不从Primary同步数据。比如你部署了一个2个节点的复制集,1个Primary,1个Secondary,任意节点宕机,复制集将不能提供服务了(无法选出Primary),这时可以给复制集添加一个Arbiter节点,即使有节点宕机,仍能选出Primary。Arbiter本身不存储数据,是非常轻量级的服务,当复制集成员为偶数时,最好加入一个Arbiter节点,以提升复制集可用性。
  Priority节点:默认为1,Priority参数设置范围在0-1000的整数值。Priority0节点的选举优先级为0,永远不会被选举为Primary。
  Vote节点:Vote默认为1,Vote参数的值在2.6版本后只能设置为0或1。Mongodb 3.0里,复制集成员最多50个,参与Primary选举投票的成员最多7个,其他成员的vote属性必须设置为0,即不参与投票。Vote设置为0时永远没有投票权。
  Hidden节点:Hidden节点不能被选为主(因为Priority为0),并且对Driver不可见。因Hidden节点不会接受Driver的请求,可使用Hidden节点做一些数据备份、离线计算的任务,不会影响复制集的服务。
  Delayed节点:delayed的配置受到opolg的影响。Delayed节点必须是Hidden节点,并且其数据落后与Primary一段时间(可配置,比如1个小时)。因Delayed节点的数据比Primary落后一段时间,当错误或者无效的数据写入Primary时,可通过Delayed节点的数据
实例
rs.add({"_id":4,“host”:“ip:port”,“priority”:1,“hidden”:false})

MongoDB学习文档相关推荐

  1. mongodb插入文档时不传ObjectId

    type BookExt struct {ID bson.ObjectId `bson:"_id"`Title string `bson:"title"`Sub ...

  2. FreeMarker中文帮助手册API文档,基础入门学习文档

    FreeMarker中文帮助手册API文档,基础入门学习文档 分类: 编程技术 发布: bywei 浏览: 7 日期: 2011年5月28日 分享到: QQ空间 新浪微博 腾讯微博 人人网 什么是Fr ...

  3. ffmpeg的中文学习文档

    ffmpeg的中文学习文档 文章目录: 一.ffmpeg介绍 二.学习参考文档 1.中文 一.ffmpeg介绍 ffmpeg是视频处理工具,可选参数非常多,功能也非常的强大,可以用来开发各种视频处理工 ...

  4. Ext JS 6学习文档-第3章-基础组件

    Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...

  5. Ext JS 6学习文档-第6章-高级组件

    Ext JS 6学习文档-第6章-高级组件 高级组件 本章涵盖了高级组件,比如 tree 和 data view.它将为读者呈现一个示例项目为 图片浏览器,它使用 tree 和 data view 组 ...

  6. NodeJS-001-Nodejs学习文档整理(转-出自http://www.cnblogs.com/xucheng)

    Nodejs学习文档整理 http://www.cnblogs.com/xucheng/p/3988835.html 1.nodejs是什么: nodejs是一个是javascript能在后台运行的平 ...

  7. java学习文档_阿里技术专家带你玩转JVM,从底层源码到项目实战,都在这份文档里...

    作为 Java 的从业者,在找工作的时候,一定会被问及关于 JVM 相关的知识. JVM 知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准.而大多数人可能没有对 JVM 的实际开发和 ...

  8. MongoDB 查询文档

    MongoDB 查询文档 语法 MongoDB 查询数据的语法格式如下: >db.COLLECTION_NAME.find() find() 方法以非结构化的方式来显示所有文档. 如果你需要以易 ...

  9. [扩展阅读] EasyGUI 学习文档【超详细中文版】

    [扩展阅读] EasyGUI 学习文档[超详细中文版] 0. 安装 EasyGUI 官网:https://github.com/robertlugg/easygui python查看内置的所有模块 h ...

最新文章

  1. 没忍住又怼同事了!领导说,要做好情绪管理:真正优秀的人,从来都是不动声色...
  2. java实现多个接口_java允许实现多个接口
  3. STM32 电机教程 11 - BLDC 6 步方波开环速度控制
  4. python-day2~3
  5. vl02n 批次拆分
  6. java防御性编程_代码防御性编程的十条技巧
  7. 模型类型与加速潜力的关系
  8. 8.Linux 高性能服务器编程 --- 高性能服务器程序框架
  9. 手机麦克风结构原理图_麦克风的分类和工作原理
  10. QQ、淘宝、阿里旺旺在线网页链接代码及详解 很实用
  11. 关于Java的点点滴滴(1)——Static关键字
  12. 父母的房产继承买卖赠予以及网络红包代金券优惠券的国家最新税法规定
  13. DB2下将16进制转为十进制
  14. openresty ngx_lua重定向
  15. 华硕主板VMware中安装Ubuntu16.04中的BIOS设置问题
  16. 上传服务器后字体文件丢失,详解Vue+elementUI build打包部署后字体图标丢失问题...
  17. 用ipad给linux做第二屏幕,让iPad变成你电脑的第二显示屏,无论工作还是生活都相当实用!...
  18. android友盟微信授权登录清除,【转载】Android友盟SDK微信授权登录接入
  19. 企业上云要几步?中拓互联奉送企业上云全攻略
  20. 写二语习得学年论文感想

热门文章

  1. 牛客网 Crazy Fences
  2. python字典排序的两种方案,并产生排名
  3. 电脑重要文件如何自动备份?
  4. Java 去除excel表格内容中的空格
  5. python程序打包成apk_Python for Android,将你的Python应用打包为APK文件
  6. textarea 手机端无法换行_处理textarea中的换行和空格
  7. python多核并行处理数据,python多进程处理数据
  8. 路由器mw320虚拟服务器,水星MW320R路由器的桥接设置步骤
  9. Eclipse注释中文格式没对齐——亲测有效
  10. Axure 表格选中和取消选中