数据库
首页 > 数据库> > 闭关修炼180天----吐血整理MongoDB的学习笔记

闭关修炼180天----吐血整理MongoDB的学习笔记

作者:互联网

MongoDB

一、MongoDB体系结构

1.1 mongoDB和NoSql

1.2 mongoDB体系结构

MongoDB -> MongoDB-database -> Collection -> document(fileid1,fileid2)

Mysql->mysql.database->tables->row(column1,column2)

1.3 mongoDB和Rdbms(关系型数据库)对比

关系型数据库 MongoDB
database(数据库) database(数据库)
table(表) collection(集合)
row(行) document(bson文档)
column(列) field(字段)
index(唯一索引、主键索引) index (支持地理位置索引、全文索引 、哈希索引)
join(主外键关联) embedded Document (嵌套文档)
primary key(指定主键) primary key (指定_id field做为主键,不指定会自动生成)

1.4什么是Bson

1.5BSON在MongoDB中的使用

MongoDB使用了BSON这种结构来存储数据和网络数据交换。把这种格式转化成一文档这个概念
(Document),这里的一个Document也可以理解成关系数据库中的一条记录(Record),只是这里的
Document的变化更丰富一些,如Document可以嵌套。

1.6 MongoDB在linux中的安装

1.7 mongo shell的启动

1.8 mongodb GUI工具

开启指定端口的命令:

二、MongoDB命令

2.1 MongoDB的基本操作

2.2MongoDB集合数据操作(CURD)

2.2.1 数据添加

  1. 插入单条数据:db.collection-name.insert(document)。

    例子:db.lagou.insert({name:"zae",salary:12,birthday:new ISODate("1996-01-01")})

  2. 插入多条数据:db.collection-name.insert([document1,document2])

  3. 插入数据时,_id字段系统会自动生成,我们也可以指定,默认生成的格式为:

    • 前四个字节为时间戳,可以通过ObjectId("对象id字符串").getTimestamp()来获取
    • 接下来的3个字节是机器码标识
    • 紧接的两个字节由进程id组成-PID
    • 最后三个字节是随机数

2.2.2 数据查询

比较条件查询:db.collection-name.find(条件)

逻辑条件查询

分页查询

db.col-name.find({条件}).sort({排序字段:排序方式}).skip(跳过的行数).limit(一页显示多少数据)

2.2.3 数据更新 调用update

$set # 设置字段值
$unset #删除指定字段
$inc #对修改的值进行自增

# 语法结构
db.col_name.update(
<query>, # 查询条件
<update>, #更新操作
 {
    upsert:<boolean>, #如果更新的是不存在的update记录,是否新增进去,默认是false不新增
    multi:<boolean>,# 默认false,只更新找到的第一条数据,如果改为true,会将查询到的多条数据都更新
    writeConcern:<document># 指定为写的行为是否需要确认
    }
)

# 举例
db.col_name.update(
{条件},
{$set:{key:value}},
{
    multi:true
 }
)

2.2.4 数据删除

db.collection.remove(
 <query>,
 {
  justOne: <boolean>,
  writeConcern: <document>
 }
)
参数说明:
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值
false,则删除所有匹配条件的文档。
writeConcern :(可选)用来指定mongod对写操作的回执行为。

2.2.5 CURD案例演示

# 插入单条数据
db.lg_resume_preview.insert({name:"zae",birthday:new ISODate("2000-09-21"),salary:15000,city:'bj'});
 
 # 插入多条数据
db.lg_resume_preview.insert([
{name:"许嵩",birthday:new ISODate("2000-09-21"),salary:18000,city:'bj'},
 {name:"徐良",birthday:new ISODate("2000-09-21"),salary:10000,city:'bj'}]);
 
 #查询所有数据
db.lg_resume_preview.find();

#等于
db.lg_resume_preview.find({name:"汪苏泷"}); 
db.lg_resume_preview.find({salary:{$eq: 15000}});

#大于
db.lg_resume_preview.find({salary:{$gt: 15000}});

#小于
db.lg_resume_preview.find({salary:{$lt: 15000}});

#不等于
db.lg_resume_preview.find({salary:{$ne: 15000}});

#and
db.lg_resume_preview.find({name:"zae",salary:15000});

#or
db.lg_resume_preview.find({$or:[{name:"许嵩"},{salary:15000}]});

#not
db.lg_resume_preview.find({name:{$not:{$eq:"薛之谦"}}});

# 在lg_resume_preview集合中查询出数据按照salary属性进行正序排序,跳过2条后,截取两条
db.lg_resume_preview.find().sort({ salary:1 }).skip(2).limit(2);

# 修改salary=18000的数据,salary为28000,只修改查询到的第一条
db.lg_resume_preview.update(
    {salary:18000}, 
    {$set:{salary:28000}}, 
    { multi: false, upsert: false}
);

# 查询出name=李白的数据,并将name设置为杜甫,salary设置为800。没有该条数据时执行插入新数据
db.lg_resume_preview.update(
    {name:"李白"}, 
    {$set:{name:"杜甫",salary:800}}, 
    { multi: false, upsert: true}
);

# 给name为杜甫的数据里面的salary值增加800
db.lg_resume_preview.update(
    {name:"杜甫"}, 
    {$inc:{salary:800}}, 
    { multi: false, upsert: false}
);

# 移除name = 杜甫的那条数据的salary字段
db.lg_resume_preview.update(
    {name:"杜甫"}, 
    {$unset:{salary:""}}, 
    { multi: false, upsert: false}
);

# 忘记操作符,会将那条数据其余字段全删掉,只剩下要更新的那个字段
db.lg_resume_preview.update(
    {name:"杜甫"}, 
    {salary:"19000"}, 
    { multi: false, upsert: false}
);

# 删除某个条件查询出的整条数据
db.lg_resume_preview.remove({salary:"19000"}, {justOne: true})

2.3 MongoDB聚合操作

2.3.1 聚合操作简介

聚合是MongoDB的高级查询语言,它允许我们通过转化合并由多个文档的数据来生成新的在单个文档
里不存在的文档信息。一般都是将记录按条件分组之后进行一系列求最大值,最小值,平均值的简单操
作,也可以对记录进行复杂数据统计,数据挖掘的操作。聚合操作的输入是集中的文档,输出可以是一
个文档也可以是多个文档

2.3.2 mongoDB聚合操作分类

2.3.3 单目的聚合操作

2.3.4 聚合管道

语法:db.col_name.aggregate([{},{}......])

mongoDB中聚合主要用于统计数据(诸如统计平均值,求和等),并返回计算的结果。

表达式 描述
$sum 计算总和
$avg 计算平均值
$min 获取集合中所有文档对应值的最小值
$max 获取集合中所有文档对应值的最大值
$push 在结果文档中插入值到一个数组中
$addToSet 在结果文档中插入值到一个数组中,但数据不重复
$first 根据资源文档的排序获取第一个文档数据
$last 根据资源文档的排序获取最后一个文档数据

聚合框架中管道常用的一些操作:(注:管道就是将上一步的操作交给下一步)

表达式 说明
$group 将集合中的文档分组,可用于统计结果
$project 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match 用于过滤数据,只输出符合条件的文档。
$limit 用来限制MongoDB聚合管道返回的文档数。
$skip 在聚合管道中跳过指定数量的文档,并返回余下的文档
$sort 在输入文档排序后输出
$geoNear 输出接近某一地理位置的有序文档

演示案例:

# 按照city进行分组,并统计每组城市出现的次数
db.lg_resume_preview.aggregate([{$group:{_id:"$city",city_count:{$sum:1}}}]);
#  按照city进行分组,并统计每组城市里面薪资的平均值
db.lg_resume_preview.aggregate([{$group:{_id:"$city",salary_avg:{$avg:"$salary"}}}]);
# 按照city进行分组,将结果放在一个数组中
db.lg_resume_preview.aggregate([{$group: { _id: "$city",city_name:{$push: "$city"}}}]);
# 按照city进行分组,将结果放在一个数组中,且结果数据不重复
db.lg_resume_preview.aggregate([{$group: { _id: "$city",city_name:{$addToSet: "$city"}}}]);
# 先进行分组,分组处理后的结果的avgSal名称修改为salary
db.lg_resume_preview.aggregate(
[{$group : {_id: "$city", avgSal:{$avg:"$salary"}}},
{$project : {city: "$city", salary : "$avgSal"}}
]);
#根据城市进行分组获取每个城市的个数,然后将个数大于3的记录统计出来
db.lg_resume_preview.aggregate([{$group: { _id: "$city",city_count:{$sum: 1}}},
{$match: {city_count:{$gt:3}}}]);

2.3.5 MapReduce编程模型

概念:MapReduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结
果合并成最终结果(REDUCE)

案例演示

db.lg_resume_preview.mapReduce(
    function(){emit(this.city,this.salary);}, #map模块,定义key - value,并传递给下一代码块
    function(key,value){              # reduce模块,接收到key,value,自动根据key分组,处理返回value的平均值
        return Array.avg(value)
    },
    {						#参数模块
        query:{salary:{$gt:15000}},  # query定义条件:例子中是只有salary大于15000的才能进入到此map中
        out:"avgSalary",                  #out存放结果集,结果集字段为avgSalary
        finalize:function(key,value){ # finalize对reduce输出的结果再一次的进行修改
            return value+100;
        },
        verbose:true #verbose结果信息中是否包含时间信息,默认为false
    
        #sort: 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
	#limit: 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)
    })

三、MongoDB索引index

3.1 什么是索引

索引是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单,能大大提高查询效率。

3.2 索引类型

3.2.1单键索引

概念:单键索引就是指的在一个字段上加的索引。

语法:db.col_name.createIndex({"字段名":排序方式})(其中1是升序,-1是降序)

特殊的单键索引 ---- 过期索引TTL:TTL索引是mongodb中一种特殊的索引,可以支持文档在一定时间之后自动过期删除,TTL索引只能在单字段上建立,并且字段类型必须是日期类型。 语法:db.co_name.createIndex({"日期字段":排序方式},{expireAfterSeconds:秒数})

演示案例:

db.createCollection("lg_test_index");

db.lg_test_index.insert({name:"张三丰",city:"上海"});

db.lg_test_index.insert({name:"张无忌",city:"洛阳",birthday:new ISODate("2020-12-31")});
# 给name创建单键索引
db.lg_test_index.createIndex({name:1});
# 给birthday创建过期索引TTL,设置过期时间为15秒,15秒之后,张无忌的那条数据会自动删除
db.lg_test_index.createIndex({birthday:1},{expireAfterSeconds:15});
# 获取所有索引
db.lg_test_index.getIndexes();

db.lg_test_index.find();

# 创建唯一索引
db.lg_test_index.createIndex({name:1},{unique,true});

3.2.2 复合索引

概念:在多个字段添加的索引(注意字段的顺序和索引方向)

语法:db.col_name.createIndex({"字段名1":排序方式},{"字段名2":排序方式})

官方详细介绍:https://www.mongodb.com/ -> Docs -> Server -> indexes

注意:如果使用字段名1和字段名2作为条件查询,索引生效;如果只使用字段名1作为条件查询,索引会生效,原因是字段名1在最左侧;如果只使用字段名2作为条件查询,索引不生效。

3.2.3 多键索引

概念:针对一个数组字段创建的索引

语法:db.col_name.createIndex({loc:排序方式})

3.2.4 地理空间索引

概念:针对地理空间坐标创建索引

语法:db.col_name.createIndex({数组的字段名:"2dsphere"或者"2d"})

演示案例

db.company.insert(
 {
 # 创建该条数据的坐标位置
  loc : { type: "Point", coordinates: [ 116.482451, 39.914176 ] },
  name: "大望路地铁",
  category : "Parks"
 }
)
# 给loc创建地理位置坐标索引
db.company.ensureIndex( { loc : "2dsphere" } )
#参数不是1或-1,为2dsphere 或者 2d。还可以建立组合索引。
#查询距离坐标[116.482451,39.914176]0.05公里以内的数据
db.company.find({
 "loc" : {
   "$geoWithin" : {
    "$center":[[116.482451,39.914176],0.05]
   }
 }
})

3.2.5 全文索引

概念:对文本内容进行查询。假设一个字段的内容是一段文本,可以给该字段建立全文索引,根据里面的文本内容进行关键字查询。一个集合仅支持建立一个全文索引。

语法:db.col_name.createIndex({field,"text"})

查询语法:db.col_name.find({"$text":{"$search":"条件值"}})

案例演示:

# 插入测试数据
db.content_test.insert({id:1,name:"z1",des:"hello zae"});
db.content_test.insert({id:2,name:"z2",des:"hello vae"});
db.content_test.insert({id:3,name:"z3",des:"but zae is not vae"});
# 查询下所有
db.content_test.find();
# 给des创建全文索引
db.content_test.createIndex({des:"text"});
# 根据des的value值的文本内容进行查询
db.content_test.find({"$text": {$search:"zae"}})

3.2.6 哈希索引

概念:针对属性的hash值进行索引查询,当使用hash索引时,程序能自动计算所需要的hash值。hash index只支持等于查询,不支持范围查询

语法:db.col_name.createIndex({"字段":"hashed"})

注意:哈希索引仅仅支持单字段,不支持同时写入组合索引中。

3.3 索引和explain分析

3.3.1 索引管理

3.3.2 explain分析

语法:db.col_name.find({}).explain()

explain()可以接收的参数:queryPlanner,executionStats,allPlansExecution

executionStats返回逐层分析:

第一层,executionTimeMillis最为直观explain返回值是executionTimeMillis值,指的是这条语句的执行时间,这个值当然是希望越少越好。
其中有3个executionTimeMillis,分别是:
executionStats.executionTimeMillis 该query的整体查询时间。
executionStats.executionStages.executionTimeMillisEstimate 该查询检索document获得数据的时间。
executionStats.executionStages.inputStage.executionTimeMillisEstimate 该查询扫描文档 index所用时间。

第二层,index与document扫描数与查询返回条目数 这个主要讨论3个返回项 nReturned、totalKeysExamined、totalDocsExamined,分别代表该条查询返回的条目、索引扫描条目、文档扫描条目。 这些都是直观地影响到executionTimeMillis,我们需要扫描的越少速度越快。 对于一个查询,
我们最理想的状态是:nReturned=totalKeysExamined=totalDocsExamined

第三层,stage状态分析 那么又是什么影响到了totalKeysExamined和totalDocsExamined?是stage的类型。
类型列举如下:
COLLSCAN:全表扫描
IXSCAN:索引扫描
FETCH:根据索引去检索指定document
SHARD_MERGE:将各个分片返回数据进行merge
SORT:表明在内存中进行了排序
LIMIT:使用limit限制返回数
SKIP:使用skip进行跳过
IDHACK:针对_id进行查询
SHARDING_FILTER:通过mongos对分片数据进行查询
COUNT:利用db.coll.explain().count()之类进行count运算
TEXT:使用全文索引进行查询时候的stage返回
PROJECTION:限定返回字段时候stage的返回

对于普通查询,我希望看到stage的组合(查询的时候尽可能用上索引):
Fetch+IDHACK
Fetch+IXSCAN
Limit+(Fetch+IXSCAN)
PROJECTION+IXSCAN
SHARDING_FITER+IXSCAN

不希望看到包含如下的stage:
COLLSCAN(全表扫描)
SORT(使用sort但是无index)
COUNT 不使用index进行count)

3.4慢查询分析

3.5 MongoDB索引底层实现原理分析

MongoDB使用B-树,所有节点都有Data域,只要找到指定索引就可以进行访问,
单次查询从结构上来看要快于MySql。

B-树是一种自平衡的搜索树,形式很简单,B-数的特点:

B+树是B-树的变种,特点如下:

四、MongoDB应用实战

4.1 MongoDB的适用场景

4.2 MongoDB的行业具体应用场景

4.3 如何选择是否使用MongoDB

注意:第一条必须满足,剩余几条满足其一可以使用,满足其二的话使用mongoDB就是十分好的选择。

4.4 Java访问MongoDB

引入依赖

<dependency>
  <groupId>org.mongodb</groupId>
  <artifactId>mongo-java-driver</artifactId>
  <version>3.10.1</version>
</dependency>

案例演示:

// 演示插入数据

public class InsertDataTest {
    public static void main(String[] args) {
        // 获取mongodb连接的客户端
        MongoClient mongoClient = new MongoClient("192.168.1.130", 27017);
        // 获取数据库
        MongoDatabase lagouDataBase = mongoClient.getDatabase("lagou");
        // 获取集合
        MongoCollection<Document> collection = lagouDataBase.getCollection("lg_resume_preview");
        // 创建document对象
        Document document = Document.parse("{name:'苏东坡',city:'开封',salary:200,birthDay:new ISODate('1997-12-31')}");
        // 执行插入
        collection.insertOne(document);
    }
}
// 演示查询数据

public class FindDataTest {
    public static void main(String[] args) {
        // 获取mongodb连接的客户端
        MongoClient mongoClient = new MongoClient("192.168.1.130", 27017);
        // 获取数据库
        MongoDatabase lagouDataBase = mongoClient.getDatabase("lagou");
        // 获取集合
        MongoCollection<Document> collection = lagouDataBase.getCollection("lg_resume_preview");
       // 指定按照salary倒叙排序
        Document sortDocument = Document.parse("{salary:-1}");
        // 获取全部数据
        FindIterable<Document> documents = collection.find().sort(sortDocument);
        for (Document document : documents) {
            System.out.println(document);
        }

    }
}
// 演示过滤数据

public class FilterDataTest {

    public static void main(String[] args) {
        // 获取mongodb连接的客户端
        MongoClient mongoClient = new MongoClient("192.168.1.130", 27017);
        // 获取数据库
        MongoDatabase lagouDataBase = mongoClient.getDatabase("lagou");
        // 获取集合
        MongoCollection<Document> collection = lagouDataBase.getCollection("lg_resume_preview");
        // 指定按照salary倒叙排序
        Document sortDocument = Document.parse("{salary:-1}");
        // 使用filters指定过滤条件进行查询
        FindIterable<Document> documents = collection.find(Filters.gt("salary",10000)).sort(sortDocument);
        for (Document document : documents) {
            System.out.println(document);
        }

    }
}

4.5 Spring访问MongoDB

引入依赖

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-mongodb</artifactId>
  <version>2.0.9.RELEASE</version>
</dependency>

配置文件编写:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">

    <mongo:db-factory id="mongoDbFactory" client-uri="mongodb://192.168.1.130:27017/lagou"></mongo:db-factory>
    <bean id="mongoTemplate"  class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg index="0" ref="mongoDbFactory"></constructor-arg>
    </bean>
    <context:component-scan base-package="com.lagou"></context:component-scan>
</beans>

MongoTemplate的运用

@Repository("resumeDao")
public class ResumeDaoImpl implements ResumeDao {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 插入一条数据
     * @param resume
     */
    public void insertResume(Resume resume) {
        mongoTemplate.insert(resume,"lg_resume");
    }

    /**
     * 单条件进行查询
     * @param name
     * @return
     */
    public Resume findResumeByName(String name) {
        Query query = new Query();
        query.addCriteria(Criteria.where("name").is(name));
        List<Resume> lgResume = mongoTemplate.find(query, Resume.class, "lg_resume");
        return lgResume.isEmpty()?null: lgResume.get(0);
    }

    /**
     * 多条件进行查询
     * @param name
     * @param salary
     * @return
     */
    public List<Resume> findByNameAndSalary(String name, Double salary) {
        Query query = new Query();
        query.addCriteria(Criteria.where("name").is(name).andOperator(Criteria.where("salary").gt(salary)));
        List<Resume> resumeList = mongoTemplate.find(query, Resume.class, "lg_resume");
        return resumeList;
    }

    /**
     * 更新数据
     * @param resume
     */
    public void updateResume(Resume resume) {
        // 确定更新哪一条数据
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(resume.getId()));

        // 更新内容
        Update update = new Update();
        update.set("name",resume.getName());
        update.set("city",resume.getCity());
        update.set("salary",resume.getSalary());
        update.set("birthday",resume.getBirthday());

        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, "lg_resume");
    }

    /**
     * 删除数据
     * @param id
     */
    public void deleteResume(String id) {
        // 确定删除哪一条数据
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        DeleteResult deleteResult = mongoTemplate.remove(query, "lg_resume");
    }
}

4.6 Spring Boot访问MongoDB

4.6.1 MongoTemplate 的方式

添加依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

配置文件:application.properties

spring.data.mongodb.host=192.168.1.130
spring.data.mongodb.port=27017
spring.data.mongodb.database=lagou

其余代码编写参考spring访问mongodb中的MongoTemplate的运用

4.6.2 MongoRepository 的方式

五、MongoDB架构

5.1 MongoDB逻辑结构

层次 描述
最上层 Client(客户端)
第二层 MongoDB Query Language(MongoDB的执行语言)
第三层 MongoDB Data Model(MongoDB的数据模型)
最底层 MongoDB的存储引擎(WriedTiger,InMemory,MMAPv1)

5.2 MongoDB的数据模型

5.2.1 描述数据模型

5.22 如何选择数据模型

5.3 MongoDB存储引擎

5.3.1 存储引擎概述

5.3.2 WriedTiger存储引擎优势

5.3.3 WriedTiger存储包含的文件和作用

5.3.4 WriedTiger存储引擎实现原理

六、MongoDB集群高可用

6.1 MongoDB主从复制架构原理和缺陷

原理:在主从结构中,主节点的操作记录成为oplog(operation log)。oplog存储在系统数据库local的oplog.$main集合中,这个集合的每个文档都代表主节点上执行的一个操作。从服务器会定期从主服务器中获取oplog记录,然后在本机上执行!对于存储oplog的集合,MongoDB采用的是固定集合,也就是说随着操作过多,新的操作会覆盖旧的操作!

缺陷:主从结构没有自动故障转移功能,需要指定master和slave端,不推荐在生产中使用。

6.2 复制集replica sets(为了解决主从复制的缺陷)

6.2.1 什么是复制集

复制集是一个集群,提供了数据的冗余备份。

复制集是一个改进后的主从。

不会去指定谁是主谁是从,主从会自动切换,保证高可用

6.2.2 为什么要使用复制集

6.2.3 复制集集群架构原理

6.2.4 复制集搭建

1.在虚拟机192.168.1.130下新建一个文件夹mongo_cluster,并执行命令tar -zxvf mongodb-linux-x86_64-rhel70-4.2.14.tgz -C mongo_cluster

2.进入到解压后的文件里(和bin同级目录),准备三个conf文件放在这,文件内容如下:

# 主节点配置 
dbpath=/data/mongo/data/server1
bind_ip=0.0.0.0
port=37017
fork=true
logpath=/data/mongo/logs/server1.log
replSet=lagouCluster
dbpath=/data/mongo/data/server2
bind_ip=0.0.0.0
port=37018
fork=true
logpath=/data/mongo/logs/server2.log
replSet=lagouCluster
dbpath=/data/mongo/data/server3
bind_ip=0.0.0.0
port=37019
fork=true
logpath=/data/mongo/logs/server3.log
replSet=lagouCluster

3.创建好配置文件中涉及到的几个目录,防止启动报错。

4.初始化节点配置

启动三个节点:./bin/mongod -f mongo_37017.conf;./bin/mongod -f mongo_37018.conf;./bin/mongod -f mongo_37018.conf

然后进入任意一个节点(我这里进入的是37017:./bin/mongo --port=37017),运行以下命令

# 配置相关信息
var cfg ={"_id":"lagouCluster",
     "protocolVersion" : 1,
"members":[
{"_id":1,"host":"192.168.1.130:37017","priority":10},
{"_id":2,"host":"192.168.1.130:37018"}
]
}

# 初始化配置
rs.initiate(cfg)
# 查看状态
rs.status()

5.节点的动态增删

#增加节点
rs.add("192.168.1.130:37019")
#删除slave 节点
rs.remove("192.168.1.130:37019")

6.复制集操作演示

7.主库切换演示

6.2.5 复制集成员的配置参数

参数字段 类型说明 取值 说明
_id 复制集标识
host 节点的主机名:ip:port
arbiterOnly 是否为仲裁节点
priority(权重) 默认1,是否有资格变成主节点,取值范围0-1000,0永远不会变成主节点。权重越大越可能成为主节点
hidden 当权重为0的时候才可以设置
votes 是否为投票节点:0不投票 1投票
slaveDelay 从库的延迟多少秒
buildIndexes 主库的索引,从库也创建,_id索引无效

案例演示:

var cfg ={"_id":"lagouCluster",
 "protocolVersion" : 1,
 "members":[
{"_id":1,"host":"192.168.1.130:37017","priority":10},
{"_id":2,"host":"192.168.1.130:37018","priority":0},
{"_id":3,"host":"192.168.1.130:37019","priority":5},
 {"_id":4,"host":"192.168.1.130:37020","arbiterOnly":true}
]
};
// 重新装载配置,并重新生成集群节点。注意重新装载配置时,需要在当时的主节点下进行配置设置
rs.reconfig(cfg)
//重新查看集群状态
rs.status()

6.2.6 有仲裁节点复制集搭建

6.3 分片集群Shard Cluster

6.3.1 什么是分片

6.3.2 为什么要分片

6.3.3 分片的原理

6.3.4 分片集群的搭建过程

1.配置 并启动config 节点集群

2.配置shard集群

3.配置路由

4.在mongo路由中添加分片节点

#进入shell操作页面
./bin/mongo --port 27017

#查看下分片状态
sh.status()

#添加分片节点
sh.addShard("shard1/192.168.1.130:37017,192.168.1.130:37018,192.168.1.130:37019");
sh.addShard("shard2/192.168.1.130:47017,192.168.1.130:47018,192.168.1.130:47019");

5.开启数据库和集合分片(指定片键)

#为数据库开启分片功能
sh.enableSharding("数据库名")
sh.enableSharding("lagou_resume")

#为指定集合开启分片功能
sh.shardCollection("数据库名.集合名",{"片键字段名如 name":索引说明})
sh.shardCollection("lagou_resume.lagou_resume_datas",{"name":"hashed"})

6.向集合中插入数据测试

use  lagou_resume;

for(var i=1;i<= 100;i++){
  db.lagou_resume_datas.insert({"name":"test"+i,
    salary:(Math.random()*20000).toFixed(2)});
}

7.验证

分别去shard1复制群和shard2复制群中查看是否有数据

七、MongoDB安全认证

7.1 用户相关操作

7.2 角色介绍

7.3.单机安全认证

7.4.集群安全认证

标签:salary,name,resume,MongoDB,db,----,索引,180
来源: https://www.cnblogs.com/zaevn00001/p/14814475.html