MongoDB-从入门到放弃之入门

重新定义OLTP数据库

On-Line Transaction Processing联机事务处理过程(OLTP)

  • 什么是MongoDB

    一个以Json为数据模型的文档数据库。

  • 为什么叫文档数据库?

文档来自于”JSON Document", 并非我们一般理解的PDF,word…

  • 主要用途

应用数据库,类似于Oracle, Mysql海量数据处理,数据平台。

  • 主要特点

建模为可选

Json数据模型比较适合开发者

横向扩展可以支持很大数据量和并发

  • 2018年开始支持事务
  • 优点:
  1. 文档模型
  2. OLTP
  3. 复制集
  4. 通过原生分片支持横向扩展能力
  5. 索引支持

feature

面向开发者的易用+高效数据库

对象模型的数据库

灵活:快速响应业务变化

多行行:同一个集合中可以包含不同字段(类型))

原生的高可用和横向扩展能力(默认最少三个节点)

Replica Set-2 to 50个成员

MongoDB CURD Operations

Insert

如果集合不存在,自动创建集合.

Insert a Single Document

db.collection.insertOne()

db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

insertOne 会返回插入文档的id属性 _id

Insert Multiple Documents

db.collection.insertMany()

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

insertMany 会返回插入成功的id信息.

  • MongoDB会自动创建集合

  • 插入语句会自动为没有包含 _id属性的文档自动生成一个 _id属性用做改文档的主键信息。

  • 所有的MongoDB的插入操作是原子性的。

Query

db.collection.find({})

db.inventory.find({})
等值查询
db.inventory.find({"qty":25})
In 查询
db.inventory.find({"qty":{$in:[50,100]}})
And
db.inventory.find({"qty":25},{"status":"A"})
Or
db.inventory.find({$or:[ {"qty":25},{"status":"A"}]})

Update

更新一条记录
db.inventory.updateOne(
{item:"paper"},
{
 $set:{"size.uom":"cm",status:"P"},
 $currentDate:{lastModified: true}
}
)

更新第一个item字段为”paper"的记录,修改它的size.uom 为 “cm",status改为:“P”,更新字段最后修改日期为当前日期。

更新多条记录
db.inventory.updateMany(
	{"qty": {$lt: 50}},
	{
	 $set:{"size.uom": "in", status:"P"},
	 $currentDate: {lastModified: true}
	}
)

Delete

删除所有记录
db.inventory.deleteMany({})
有条件的删除记录
db.inventory.deleteMany({"status": "A"})
删除一条记录
db.inventory.deleteOne({status: "D"})

会删除所有匹配中的记录中的第一条记录

文本查找

Example data:

db.stores.insert(
   [
     { _id: 1, name: "Java Hut", description: "Coffee and cakes" },
     { _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
     { _id: 3, name: "Coffee Shop", description: "Just coffee" },
     { _id: 4, name: "Clothes Clothes Clothes", description: "Discount clothing" },
     { _id: 5, name: "Java Shopping", description: "Indonesian goods" }
   ]
)

创建索引

db.stores.createIndex({name: "text", description: "text"})

$text

通过$text 使用 text 索引 执行查找,并且在文本通过空格表示or连接符

db.stores.find( { $text: { $search: "java coffee shop" } } )

准确条件时的查询为了避免错误的将空格理解为or,通过 \ 转义

db.stores.find( { $text: { $search: "\"coffee shop\"" } } )

排除文本操作, 使用 - 表示不包含

db.stores.find( { $text: { $search: "java shop -coffee" } } )

排序

db.stores.find(
   { $text: { $search: "java coffee shop" } },
   { score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } )

todo:

  1. 地理位置查询
  2. 读隔离,写确认
  3. 原子性和事务性

在执行写操作的时候,单记录的写操作是原子性的。如果写操作是多记录的,原子性也是体现在单条记录的操作上,

在一次写操作上,如果操作记录是涉及多条记录的情况,在整体的多行操作上不是原子性的。如果在执行当前写操作过程中,如果有其他线程同样执行写操作,就有可能会发生交叉操作的情况,从4.0版本开始,MongoDB支持在复制集上支持多记录上的事务性。在4.2版本开始支持分布式事务。

并发控制
  1. 通过在制定字段上创建唯一索引,具体实现如:

update() and Uniqueand findAndModify() and Unique Index

Aggregation

Aggregation Framework是一个计算框架

管道(Pipleline)和步骤(Stage)

  • 整个聚合运算过程称为pipleline,它是由多个步骤(Stage)组成的,每个管道:
  1. 接受一系列文档(原始数据)
  2. 每个步骤对这些文档进行一系列运算;
  3. 结果文档输出给下一个步骤;

聚合运算的基本格式

Pipleline = [$stage1, $stage2, #stage3, …]

db..aggregate(

Pipleline,

{options}

)

常见步骤

$match 过滤 lt gt and or…

$project 投影 map reduce …

$sort 排序 sum avg push addtoSet

$group 分组

s k i p / skip/ skip/limit 结果限制

$lookup 左外链接

$unwimd 展开数组

$bucket 分组统计

$facet 聚合bucket.

Demo:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJQlPbaU-1584866771729)(/Users/leejiliang/Library/Application Support/typora-user-images/image-20200322093608659.png)]

db.orders.aggregate([
   { $match: { status: "A" } },
   { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
Optimization
  1. Projection

通过截取一个Collection的部分内容来优化查询结果。删除一些不必要的字段信息。

  1. Sequence

Replication

复制集作用

  1. 实现服务高可用
  2. 数据分发:将数据从一个区域复制到另外一个区域,减少另一个区域的读延迟
  3. 读写分离:不同类型的压力分散在不同的节点上执行
  4. 异地容灾:在数据中心故障时快速切换到其他服务器
实现的原理
  1. 数据写入时将数据迅速复制到另一个独立节点上
  2. 在接受写入的节点发生故障时自动选举出一个新的节点代替主节点

典型复制集结构

三个以上具有投票权的节点组成典型复制集,包括:

  1. 一个主节点(PRIMARY) : 接受写入操作和选举时投票
  2. 多个从节点(SECONDARY) : 复制主节点上的新数据和选举时负责投票
  3. Arbiter(选举节点)
replication

数据复制过程

  • Mongo会在主节点发生变更时,将变更操作记录下来(类似Mysql binLog),记录称为:oplog.

  • 从节点通过不断的获取主节点上oplog的变动信息,在从节点上执行以保证跟主节点保持数据一致。

copy-process

选举过程

  • 具有投票权的节点之间两两发送心跳,保持节点状态被可知;

  • 5次心跳未收到时判断为节点故障

  • 如果故障的是主节点,从节点会发起选举,选举出新的节点

  • 如果是从节点,不会发起选举

  • 选举是基于(RAFT一致性算法)实现,选举成功的必要条件是(大多数投票节点存活)

  • 复制集中最多可以有50个节点,但是选举节点最多有7个。

影响选举的因素
  1. 整个集群必须有大多数节点存活
  2. 被选举为主节点的节点要求:
  • 能够与多数节点建立连接
  • 具有比较新的oplog
  • 如果配置了优先级,优先选择优先级比较高的节点

复制集节点可选配置项

  • 是否具有投票权

  • priority 被选举为主节点的优先级, 为0时不能被选举为主节点

  • hidden 用于复制数据,但是对应用不可见,可以拥有投票权,优先级必须设置为0,被用来做安全备份

hidden-node
  • slaveDelay 延迟复制主节点数据,和主节点保持一点的时间差,用于防止误操作。
slaveDelay-node

Replication 搭建

  1. 创建三个数据文件夹
sudo mkdir /usr/local/mongodb/data/db{1,2,3}
  1. 为3个mongoDB准备三份配置文件
systemLog:
  destincation: file
  path: /usr/local/mongodb/data/db1/mongod.log    # log path
storage:
  dbPath: /usr/local/mongodb/data/db1   # data directory
net:
  bindIp: 0.0.0.0
  port: 28017   # port
replication:
  replSetName: rs0
processManagement:
  fork: true

需要分别为每个配置文件修改日志路径,数据文件路径,和端口号信息

  1. 启动
sudo mongod -f db1/mongod.conf
  1. 查看启动结果
ps -ef | grep mongod

mongod-ps

  1. 配置复制集
  • Mongo --port 28107

    rs.initiate({
    	_id: "rs0",
    	members: [{
    		_id: 0,
    		host: "localhost:28017"
    	},{
    		_id: 1,
    		host: "localhost:28018"
    	},{
    		_id: 2,
    		host: "localhost:28019"
    	}]
    })
    
    
    1. 查看复制集状态:
    # rs.status()
    

    replication-setinfo

    在从节点上执行查询操作时提示:"errmsg" : "not master and slaveOk=false", 通过执行指令:rs.slaveOk()即可解决.

参考:
MonngoDB官网 https://docs.mongodb.com/manual/
极客时间: MongoDB高手课

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值