C++ 全栈知识体系C++ 全栈知识体系
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
  • 数据库原理

    • 数据库原理 - MySQL概述
    • 数据库原理 - 数据库是如何工作的
  • SQL语言

    • SQL语言 - 知识体系结构
    • SQL语言 - 语法
    • SQL语言 - 约束
    • SQL语言 - 函数
    • SQL语言 - 连接查询
    • SQL语言 - 多表查询
    • SQL语言 - 子查询
    • SQL语言 - 使用技巧
  • SQL - MySQL

    • MySQL基础

      • ♥MySQL语言知识体系详解♥
      • MySQL基础 - 基本概念
      • MySQL基础 - 三范式
      • MySQL基础 - 数据类型
      • MySQL基础 - 视图
      • MySQL基础 - 存储过程
    • MySQL进阶

      • MySQL进阶 - 存储引擎
      • MySQL进阶 - InnoDB引擎
      • MySQL进阶 - 索引基础
      • MySQL进阶 - 聚簇索引和非聚簇索引
      • MySQL进阶 - 索引使用
      • MySQL进阶 - SQL性能分析
      • MySQL进阶 - SQL性能优化
      • MySQL进阶 - 锁
      • MySQL进阶 - 触发器
      • MySQL进阶 - 事务
      • MySQL进阶 - 管理工具
    • MySQL运维

      • MySQL运维 - 主从复制
      • MySQL运维 - 分库分表
      • MySQL运维 - 读写分离
      • MySQL进阶 - 日志分析
    • MySQL实战

      • MySQL实战 - 一条 SQL 的执行过程详解
      • MySQL实战 - SQL是如何解析的
      • MySQL实战 - MyCat使用
  • NoSQL - Redis

    • Redis基础 - 简介
    • Redis基础 - 命令
    • Redis进阶 - 持久化
    • Redis进阶 - 事务
    • Redis进阶 - 删除策略
    • Redis进阶 - 主从复制
    • Redis进阶 - 哨兵模式
    • Redis应用 - 集群概念以及应用
    • Redis应用 - 企业级解决方案
  • NoSQL - ElasticSearch

    • ElasticSearch集群 - 概念
    • ElasticSearch集群 - 安装
    • ElasticSearch集群 - 部署
    • ElasticSearch数据 - 分析与处理
    • ElasticSearch数据 - 搜索
    • ElasticSearch数据 - 存储
    • ElasticSearch应用 - ES与MySQL数据同步

ElasticSearch数据 - 存储

主要介绍elasticsearch的数据存储功能,包括索引库操作和文档操作。

  • 分词器
  • mapping映射属性
  • 索引库操作
  • 文档操作-动态映射
  • 数据库导入
  • mapping映射分析

参考资料

  • 安装elasticsearch
  • elasticsearch官网

安装elasticsearch

主要步骤:

  1. docker load -i 加载 es 和 kibana的镜像;
  2. docker run + 配置参数,依次启动es和kibana;
  3. 在kibana提供的DevTools界面,编写DSL来操作elasticsearch;
  4. 安装ik分词器、配置扩展词词典、以及再次测试验证。

分词器

分词器的作用: - 创建倒排索引时对文档分词 - 用户搜索时,对输入的内容分词

处理中文分词,一般会使用IK分词器。https://github.com/medcl/elasticsearch-analysis-ik

ik分词器包含两种模式:

  • ik_smart:最少切分,粗粒度
  • ik_max_word:最细切分,细粒度

示例:输入“小黑子”

  • ik_smart拆分结果:"小","黑子"
  • ik_max_word拆分结果:"小黑"、"黑子"

而且会有打分机制,根据分词的匹配程度score字段。

ik分词器-拓展词库

ik分词器-拓展词库

ik分词器-停用词库

ik分词器-停用词库

索引库操作

索引库就类似数据库表,mapping映射就类似表的结构。我们要向es中存储数据,必须先创建“库”和“表”。

mapping映射属性

mapping是对索引库中文档的约束,常见的mapping属性包括:

  • type:字段数据类型,常见的简单类型有:
    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
    • 数值:long、integer、short、byte、double、float、
    • 布尔:boolean
    • 日期:date
    • 对象:object
  • index:是否创建索引,默认为true
  • analyzer:使用哪种分词器
  • properties:该字段的子字段

例如下面的json文档:

{
    "age": 21,
    "weight": 52.1,
    "isMarried": false,
    "info": "黑马程序员Java讲师",
    "email": "zy@itcast.cn",
    "score": [99.1, 99.5, 98.9],
    "name": {
        "firstName": "云",
        "lastName": "赵"
    }
}

对应的每个字段映射(mapping):

  • age:类型为 integer;参与搜索,因此需要index为true;无需分词器
  • weight:类型为float;参与搜索,因此需要index为true;无需分词器
  • isMarried:类型为boolean;参与搜索,因此需要index为true;无需分词器
  • info:类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart
  • email:类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器
  • score:虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器
  • name:类型为object,需要定义多个子属性
    • name.firstName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器
    • name.lastName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器

注意: mapping约束中,keyword:表明不需要分词;index为false为不参加搜索,能够加快搜索速度。

索引库操作

  • 创建索引库:PUT /索引库名
  • 查询索引库:GET /索引库名
  • 删除索引库:DELETE /索引库名
  • 添加字段:PUT /索引库名/_mapping
#创建索引库
PUT /student
{
  "mappings": {
    "properties": {
      "name":{
        "type": "keyword"
      },
      "age":{
        "type": "integer"
      },
      "school":{
        "type": "text", 
        "analyzer": "ik_smart"
      }
    }
  }
}

#查看索引库
GET /student

#删除索引库
DELETE /student

#更新索引库
PUT /student/_mapping
{
  "properties":{
    "id":{
      "type":"integer"
    }
  }
}

文档操作

文档操作包括以下几种:

  • 创建文档:POST /{索引库名}/_doc/文档id { json文档 }
  • 查询文档:GET /{索引库名}/_doc/文档id
  • 删除文档:DELETE /{索引库名}/_doc/文档id
  • 修改文档:
    • 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }
    • 增量修改:POST /{索引库名}/_update/文档id { "doc": {字段}}
#新增文档
POST /student/_doc/1
{
  "age": "25",
  "id": "1001",
  "name": "Jason",
  "school": "南京理工大学"
}

POST /student/_doc/2
{
  "age": "24",
  "id": "0005",
  "name": "Hellen",
  "school": "东南大学"
}

POST /student/_doc/3
{
  "age": "27",
  "id": "1011",
  "name": "Steven",
  "school": "南京大学"
}

#查询文档
GET /student/_doc/1

GET /student/_doc/2

GET /student/_doc/3

#修改文档
#增量修改
POST /student/_update/1
{
  "doc":{
  "id": "1003"
  }
}

#全量修改
PUT /student/_doc/1
{
  "age": "25",
  "id": "1007",
  "name": "Bob",
  "school": "南京理工大学"
}

#删除文档
DELETE /student/_doc/3

文档操作-动态映射

当我们向ES中插入文档时,如果文档中字段没有对应的mapping,ES会帮助我们字段设置mapping,规则如下:

文档操作-动态映射

#动态映射
PUT /student/_doc/1
{
  "age": "25",
  "id": "1007",
  "name": "Bob",
  "school": "南京理工大学",
  "city":"南京",
  "sex": "male"
}

#查看索引库,会发现默认帮我们新增了city和sex的mapping约束
GET /student
"student" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "integer"
        },
        "city" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "id" : {
          "type" : "integer"
        },
        "name" : {
          "type" : "keyword"
        },
        "school" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        },
        "sex" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }

RestClient操作索引库学习

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html

其中的Java Rest Client又包括两种:

  • Java Low Level Rest Client
  • Java High Level Rest Client

RestClient

数据库导入

以hotel.sql的数据为例:

数据结构如下:

CREATE TABLE `tb_hotel` (
  `id` bigint(20) NOT NULL COMMENT '酒店id',
  `name` varchar(255) NOT NULL COMMENT '酒店名称;例:7天酒店',
  `address` varchar(255) NOT NULL COMMENT '酒店地址;例:航头路',
  `price` int(10) NOT NULL COMMENT '酒店价格;例:329',
  `score` int(2) NOT NULL COMMENT '酒店评分;例:45,就是4.5分',
  `brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',
  `city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',
  `star_name` varchar(16) DEFAULT NULL COMMENT '酒店星级,从低到高分别是:1星到5星,1钻到5钻',
  `business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹桥',
  `latitude` varchar(32) NOT NULL COMMENT '纬度;例:31.2497',
  `longitude` varchar(32) NOT NULL COMMENT '经度;例:120.3925',
  `pic` varchar(255) DEFAULT NULL COMMENT '酒店图片;例:/img/1.jpg',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

mapping映射分析

创建索引库,最关键的是mapping映射,而mapping映射要考虑的信息包括:

  • 字段名
  • 字段数据类型
  • 是否参与搜索
  • 是否需要分词
  • 如果分词,分词器是什么?

其中:

  • 字段名、字段数据类型,可以参考数据表结构的名称和类型
  • 是否参与搜索要分析业务来判断,例如图片地址,就无需参与搜索
  • 是否分词呢要看内容,内容如果是一个整体就无需分词,反之则要分词
  • 分词器,我们可以统一使用ik_max_word

来看下酒店数据的索引库结构:

PUT /hotel
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

几个特殊字段说明:

  • location:地理坐标,里面包含精度、纬度
  • all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索
Last Updated:
Contributors: klc407073648
Prev
ElasticSearch数据 - 搜索
Next
ElasticSearch应用 - ES与MySQL数据同步