doc es 中type_canal 系列:ES中nested嵌套类型同步

本文介绍了如何在ES中使用nested类型进行数据同步,通过canal-adapter进行配置,包括表结构设计、测试数据准备、canal-adapter的nested配置细节,以及同步后的结果验证和搜索查询。
摘要由CSDN通过智能技术生成
在日常的业务开发场景中,像 一个人有多套房子,多个住址 ,一篇文章中有多个评论这种需求还是非常常见的。当我们使用 Elasticsearch 来进行存储时, ES 的字段类型是 nested 类型 ,虽然这个效率不高。 当我们使用 canal 对数据进行增量同步到 ES 时,canal-adapter 是否是支持 nested 类型呢?

查看 issue 提问

bf8bed1d646a6612151f4223bb4528db.png

好遗憾。大佬说暂时不支持。 在本想放弃的时候,看到 issue 中有位小伙伴说,配置 object 兼容 nested ,但是并没有给出解决方案。废话不多说,实践一把,走起。

1. 数据处理

1.1 创建 存在 字段类型为 nested 的索引 canal_test

首先创建 elasticsearch的索引名为 canal_test  ,其中 addresses 字段是 nested 类型
curl -XPUT "http://localhost:9200/canal_test" -H 'Content-Type: application/json' -d'{  "settings": {    "number_of_shards": 1  },  "mappings": {    "dynamic": false,    "properties": {      "addresses": {        "type": "nested",        "properties": {          "address": {            "analyzer": "ik_max_word",            "type": "text"          },          "houseId": {            "type": "long"          },          "zxbs": {            "type": "long"          },          "jwhdm": {            "type": "keyword"          },          "id": {            "type": "long"          }        }      },      "death": {        "type": "boolean"      },      "gender": {        "type": "keyword"      },      "nation": {        "type": "keyword"      },      "zxbs": {        "type": "keyword"      },      "name": {        "type": "keyword",        "fields": {          "fulltext": {            "type": "text"          }        }      },      "residentId": {        "type": "long"      },      "type": {        "type": "long"      }    }  }}'

1.2 表结构

创建 两张表 t_address(地址表),t_rk (人口表)。一个人可以有多个地址,一对多的关系
CREATE TABLE `t_address` (  `address` varchar(255) DEFAULT NULL,  `houseId` int(11) DEFAULT NULL,  `zxbs` int(11) DEFAULT NULL,  `jwhdm` varchar(255) DEFAULT NULL,  `id` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `t_rk` (  `residentId` int(11) NOT NULL AUTO_INCREMENT,  `type` int(255) DEFAULT NULL,  `zxbs` varchar(255) DEFAULT NULL,  `name` varchar(255) DEFAULT NULL,  `nation` varchar(255) DEFAULT NULL,  `gender` varchar(255) DEFAULT NULL,  `death` char(1) DEFAULT NULL,  PRIMARY KEY (`residentId`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

1.3测试数据

INSERT INTO `demo`.`t_rk`(`residentId`, `type`, `zxbs`, `name`, `nation`, `gender`, `death`) VALUES (3, 1, '1', 'huang123', '113', '1', '1');INSERT INTO `demo`.`t_address`(`address`, `houseId`, `zxbs`, `jwhdm`, `id`) VALUES ('厦门', 12, 23, '23', 3);INSERT INTO `demo`.`t_address`(`address`, `houseId`, `zxbs`, `jwhdm`, `id`) VALUES ('漳州', 233, 23, '23', 3);INSERT INTO `demo`.`t_address`(`address`, `houseId`, `zxbs`, `jwhdm`, `id`) VALUES ('泉州', 233, 23, '23', 3);

2. canal-adapter 配置

默认已经熟悉 canal 和 canal-adapter 的使用。在同步到 es 中,我们知道需要为每个索引配置一份 yml 的配置文件,下面创建canal_test.yml 文件 ,同步配置如下

2.1 nested 配置的正确姿势

dataSourceKey: defaultDSdestination: examplegroupId: g1esMapping:  _index: canal_test  _type: _doc  _id: _id  upsert: true#  pk: id  sql: "SELECT        t1.residentId AS _id,        t1.`name`,        t1.death,        t1.gender,        t1.nation,        t1.type,        t1.zxbs,        CONCAT('[',c.address,']') AS  addresses        FROM        t_rk t1        LEFT JOIN (        SELECT        id,        GROUP_CONCAT(JSON_OBJECT('address',address,'houseId',houseId)) AS address        FROM        t_address        GROUP BY        id      ) c ON c.id = t1.residentId"  objFields:    addresses: object#  etlCondition: "where a.c_time>={}"  commitBatch: 3000

* 重点关注

  1. sql写法

SELECT        t1.residentId AS _id,        t1.`name`,        t1.death,        t1.gender,        t1.nation,          t1.type,        t1.zxbs,        CONCAT('[',c.address,']') AS  addresses        FROM        t_rk t1        LEFT JOIN (        SELECT        id,        GROUP_CONCAT(JSON_OBJECT('address',address,'houseId',houseId)) AS address        FROM        t_address        GROUP BY        id      ) c ON c.id = t1.residentId"
  1. 配置中的关键

  objFields:    addresses: object

2. 测试同步情况

  1. 获取第 1 步中准备的sql,执行测试数据 sql

  2. canal 执行日志

b6503a7313613ed78a30242a02658bec.png

  3.  同步结果

       b28cb4ed8fd5c85fb2e128a95d706103.png

4. 搜索验证 

GET canal_test/_search{  "query":{    "bool": {      "must": [        {          "nested": {            "path": "addresses",            "query": {              "bool": {                "must": [                  {                    "match_phrase": {                      "addresses.address": "漳州"                    }                  }                ]              }            }          }        }      ]    }  }}

查询结果:

    51962fec1438faf470940b900bf55993.png

好了 ,今天的实践就到这里。你学废了吗? 

  47cc986e849ec8e60bc13e1bc6f52aa6.png

                                                                       
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值