背景

  • 从开发的角度说,就是老板叫我用es了,没那么多为什么,爸爸说了算
  • 从业务角度,mysql已经不能满足我对全文检索的需求了。我需要检索某一个字段包含"圣诞节刚刚过去"这一字符串的记录。这对mysql是个很头疼的问题,但在es中,是个很简单的事。
  • 此外es结合kibana还能实现很多数据可视化和数据分析的功能。

问题

  1. mysql的结构化数据如何平铺成es中的文档结构的数据
  2. 使用什么方式把数据本身从mysql迁移到es中

解决方案

如果你被上述问题困扰过,可以参考以下方案

  1. mysql的结构化数据如何平铺成es中的文档结构的数据

设定index的mapping

这里需要介绍三种字段的type,分别是 objectnestedjoin

object

现在有个问题,下面的数据如何存入到es中呢,它对应的mapping应该是什么样的呢

{
"name": "BeJson",
"url": "http://www.bejson.com",
"page": 88,
"isNonProfit": true,
"address": {
"street": "科技园路.",
"city": "江苏苏州",
"country": "中国"
},
"links": [
{
"name": "Google",
"url": "http://www.google.com"
},
{
"name": "Baidu",
"url": "http://www.baidu.com"
},
{
"name": "SoSo",
"url": "http://www.SoSo.com"
}
]
}

name、url这些字段好处理,直接设定字段"type" : "text"或者"type" : "keword"或者

"type" : "text",//text类型全文搜索
"fields" : {
"keyword" : {
"type" : "keyword",//keyword支持聚合查询
"ignore_above" : 256
}
}

就行了,但是对于address和links,这种里面包含json对象,或者数组的,怎么处理呢。这里可以采用"type" : "object"来处理。如下

{
"address": {
"type": "object",
"properties": {
"street": {
"type": "text"
},
"city": {
"type": "text"
},
"country": {
"type": "text"
}
}
},
"links": {
"type": "object",
"properties": {
"name": {
"type": "text"
},
"url": {
"type": "text"
}
}
}
}

可能会对links有疑问,它明明是数组,却怎么和address的设置类似。其实es中是没有单独的数组这一类型,因为他所有的字段都支持数组,比如你是text,你可以放多个值进去,以name为例,你可以放"name":["张三", "李四"]这样的数据进去。

而且,es默认对这种嵌套结构建立的索引就是object类型, "type": "object"可以省略

于是可以变为下面这样

{
"address": {
"properties": {
"street": {
"type": "text"
},
"city": {
"type": "text"
},
"country": {
"type": "text"
}
}
},
"links": {
"properties": {
"name": {
"type": "text"
},
"url": {
"type": "text"
}
}
}
}

甚至,通过添加properties,可以无限嵌套下去。

下面说object类型的缺点了,缺点也是由它本身结构导致的

对于数组结构,是这么存储数据的,以上面的address为例,他会把json结构平铺开,然后把所有这个字段的值放在平铺后的字段上:

"links.name" : ["Google","Baidu","SoSo"]
"links.url" : ["http://www.google.com","http://www.baidu.com","http://www.soso.com"]

这在查询时就出现问题了,本来Google和http://www.google.com是绑定的,但是这种结构无法满足这种绑定的关系,也就是如果你想查name是Baidu,并且url是http://www.google.com的,竟然也能查出来,而这和前面所插入的文档内容不符。

所以需要nested结构和join结构出场了

nested

嵌套结构解决了我们查询嵌套文档字段的问题,同样的,也可以解决,在es中实现类似mysql的join查询的问题。

外键就需要设置为nested(虽然现在设计表几乎不用外键约束了,但外键的逻辑还是在的 )

另外,nested字段本身会形成一个文档,只不过是嵌套在大的文档下,所以在统计索引的文档数时,实际上是最外层的文档数加上nested字段形成的文档数

{
"mappings": {
"properties": {
"orderNo": {
"type": "text"
},
"finance": {
"type": "nested",
"properties": {
"no": {
"type": "text"
},
"name": {
"type": "text"
}
}
},
"dengdeng": {
"type": "nested",
"properties": {
"no": {
"type": "text"
},
"name": {
"type": "text"
}
}
}
}
}
}

这里需要注意,以nested里面的字段为查询条件,需要修改下查询DSL,在外层加一层nested,每有一层nested嵌套关系,就需要加一层

{
"query": {
"nested": {
"path": "finance",
"query": {
"bool": {
"must": [{
"match": {
"finance.no": "1234"
}
},
{
"match": {
"finance.name": "bob"
}
}
]
}
}
}
}
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

这里有官方描述

由于es本身对文档通过nested字段进行了绑定,索引更新数据时,整个文档都会被替换,代价会大一些,但是由于关系绑定好了,查询会快一些。这里的代价大一些,查询快一些自然就是和join类型对比啦。

join

join 其实有父子文档的概念,父文档通过一个字段关联一个子文档,

这个结构比较复杂的是在你推数据时,需要指定对应的父文档是哪个

mapping结构如下

{
"mappings": {
"properties": {
"order_relation": {
"type": "join",
"relations": {
"order": ["comment", "finance", "dengdeng"]
}
},
"orderNo": {
"type": "text"
},
"comment": {
"type": "text"
},
"finance": {
"type": "keyword"
},
"dengdeng": {
"type": "text"
}
}
}
}

解释一下

  • 6.x版本之后没有指定的type了,都是_doc

  • 所以将所有表的字段都建在一个索引中,不可以分type区分父子文档了。比如orderNo是order表,comment是评论表,finance是金融单表,这里一个字段代表一个表,为了简化嘛

  • 新增一个字段order_relation,里面规范了父子关系,以后新增一个文档时,都加上这个字段,里面的值表面这个文档的身份,"order": ["comment", "finance", "dengdeng"]表示的是order是父文档,comment、finance、dengdeng是子文档。

  • 新增父文档时不用指定id,只需指定身份

    PUT index/_doc/1?refresh
    {
    "order_no": "1234",
    "order_relation": "order"
    }
    //表明我这个文档是父文档
  • 新增子文档时需要指明身份,也需要指定你这个子文档绑定的是哪个父文档

PUT index/_doc/3?routing=1&refresh
{
"comment": "This is an answer",
"order_relation": {
"name": "comment",
"parent": "1"
}
}

优点就是更新数据时,不用连带着父子文档一起改,缺点是查询效率不如nested结构

  1. 使用什么方式把数据本身从mysql迁移到es中

以后再说吧

9.mysql的数据迁移到es中的更多相关文章

  1. 使用logstash拉取MySQL数据存储到es中的再次操作

    使用情况说明: 已经使用logstash拉取MySQL数据存储到es中,es中也创建了相应的索引,也存储了数据.假若把这个索引给删除了,再次进行同步操作的话要咋做,从最开始的数据进行同步,而不是新增的 ...

  2. Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

    一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...

  3. 1.scrapy爬取的数据保存到es中

    先建立es的mapping,也就是建立在es中建立一个空的Index,代码如下:执行后就会在es建lagou 这个index.     from datetime import datetime fr ...

  4. seata服务端和客户端配置(使用nacos进行注册发现,使用mysql进行数据持久化),以及过程中可能会出现的问题与解决方案

    seata服务端和客户端配置(使用nacos进行注册发现,使用mysql进行数据持久化),以及过程中可能会出现的问题与解决方案 说明: 之所以只用nacos进行了注册与发现,因为seata使用naco ...

  5. mysql 数据库数据迁移 The user specified as a definer ('root'@'%') does not exist 解决方法

    从一个数据库数据迁移到本地localhost 程序在调用到数据库的视图时报错,直接在数据库中打开视图时也报错,类似: mysql 1449 : The user specified as a defi ...

  6. MySQL大数据迁移备份

    MySQL迁移通常使用的有三种方法:   1.数据库直接导出,拷贝文件到新服务器,在新服务器上导入. 2.使用第三方迁移工具. 3.数据文件和库表结构文件直接拷贝到新服务器,挂载到同样配置的MySQL ...

  7. MySQL数据库数据迁移到SQLserver

    近期因工作须要.须要将mysql数据库迁移到sqlserver.不过数据迁移.因此相对照较简单.对于mysql迁移到sqlserver,我们须要使用到mysql odbc驱动,然后透过sqlserve ...

  8. Mysql ---Sqlserver数据迁移到Mysql(Mysql建表迁移数据)

    1 试用了MysqlWorkBench的数据迁移功能 以为能实现:建立跟Sqlserver一样的表结构和视图的功能,sqlserver的数据迁移到mysql 实际上发现:即使勾选了表和视图,实际上却只 ...

  9. mysql将视图数据迁移到表中

    #字段必须完全一样 INSERT into table1(所有字段) select * from data.视图

  10. bat脚本,winscp,shell加mysql存储过程实现mysql单条数据迁移

    起因 公司有个任务,需要迁移mysql中的单条数据.从公司的dev环境到staging环境,dev环境的mysql安装在windows server 2012 R2下,stage是aws的服务器不能直 ...

随机推荐

  1. Solution Set -「ARC 111」

    「ARC 111A」Simple Math 2 Link. \(\lfloor \frac{10^N - kM^2}{M} \rfloor \equiv \lfloor \frac{10^N}{M} ...

  2. spark修改控制台输出日志级别

    spark修改控制台输出日志级别 修改conf/log4j.properties cd $SPARK_HOME/conf cp log4j.properties.template ./log4j.pr ...

  3. [CISCN 2019华东南]Web11

    看到下面connection 里面的内容有一点像抓包出来的 就抓包试试 似乎感觉也没有什么用 看到这个东西,那么就想到改IP 添加X-Forwarded-For:127.0.0.1 发现这个IP随着我 ...

  4. 以效率为导向:用ChatGPT和HttpRunner实现敏捷自动化测试(二)

    1.前言 在上一篇文章: 利用ChatGPT提升测试工作效率--测试工程师的新利器(一)中,我们提到了如何通过chatGPT生成单接口测试用例,然后再让chatGPT去根据测试用例去生成接口自动化脚本 ...

  5. 造轮子之集成GraphQL

    先简单对比以下GraphQL和WebAPI:GraphQL和Web API(如RESTful API)是用于构建和提供Web服务的不同技术. 数据获取方式: Web API:通常使用RESTful A ...

  6. .NET6发布项目到腾讯云Windows2012R全网最详细教程

    注意:本次使用腾讯云作为本次的演示 1.创建服务器及连接 1.1 请先在腾讯云.阿里云等创建实例 1.2 打开远程连接工具输入在腾讯云获取的公网iP输入计算机 1.3 根据图片点击连接 1.4 输入服 ...

  7. JVM 学习

    目录 1. 类加载器及类加载过程 1.1 基本流程 1.2 类加载器子系统作用 1.3 类加载器角色 1.4 加载过程 (1) 加载 loading (2) 链接 linking 验证 verify ...

  8. 2021入门Webpack,看这篇就够了:Webpack.config.js 解析

    这是一个webpack配置说明 本文是发布在github上webpack-demo的README文件内容. 主要对webpack.config.js每一条的注释说明. 希望浏览效果更佳,可以点击文章最 ...

  9. DS18B20初始化-读-写-温度转换

    DS18B20 (一)初始化 (二)读字节 (三)写字节 (四)温度转换 1获得数据 2转换数据 (一)初始化 初始化时序: 数据线先拉到高电平,稍作延时即可(刚开始是高电平还是低电平芯片手册上其实不 ...

  10. QGradient渐变填充

    QGradient渐变填充 QGradient (一)简介 (二)枚举类型 1.spread 2.CoordinateMode 3.type (三)常用函数 1.coordinateMode() 2. ...