本文展示了一个Elasticsearch预处理技巧的实例分析,简洁易懂,绝对能让你大放异彩。希望通过这篇文章的详细介绍,你能有所收获。
00-101010
1、上问题
es可以根据_id字符串进行分段和聚合。例如,数据1,_id=C12345数据2,_id=C12456数据3和_id=C31268。
根据es汇总统计,有两个数字以C1开头,一个数据以C3开头。
这个API怎么写,在老大哥的指导下?
00-1010,插入的时候,能不能把原始数据转换到一定程度,然后索引?
{
标题' :{
用户信息' :[
{\ '密码' : \ ' test \ ',\n '用户名' : \ ' zy \ ' } '
]
}
}
里面已经有一个字符串了。你能在数据插入阶段把这个json转换成一个对象吗?
1.1 线上实战问题 1——字符串切分
我想给列表的每个值添加一个字符:
例如,像{'tag':['a ',' b ',' c']这样的文档}我希望像{'tag':['a2 ',' b2 ',' c2']},
你试过把foreach和script一起使用吗?
00-1010「问题 1」:分析环节需要聚合统计,当然也可以用无痛脚本实现,但由于数据量大,势必会出现性能问题。
您可以将数据处理放在前面,提取first _id字符,并将它们视为一个字段。
「问题 2」:在写作时,我希望进行字符类型转换,并将复杂的字符串转换为格式化的对象数据。
「问题 3」:所有阵列类型数据都定期更新。当然,无痛脚本脚本也可以实现。
但是在写作过程中,后期分析过程的负担可以大大减轻。
对于以上三个问题,在编写之前先用java或python编写,然后写入Elasticsearch也是一种解决方案。
然而,如果你想拼命,有没有更好的计划?写之前可以对数据进行预处理吗?
00-1010一般来说,当我们的程序从第三方数据源(Mysql、Oracle、HBase、Spark等)写入数据或导入数据时。),它们都是原始数据的样子,与ES直接批量同步并由ES索引的数据就是它的样子。如下图所示:
如上所述,对于这三个实际问题,实际的业务数据可能并不是我们在分析中真正需要的。
有必要对这些数据进行合理的预处理,以便于后续环节的分析和数据挖掘。
数据预处理的步骤大致分解如下:
数据清理。主要是去除重复数据、噪声(即干扰数据)和填写默认值。
数据集成。将来自多个数据源的数据放在统一的数据存储中。
数据转换。将数据转换为适合数据挖掘或分析的形式。
存在
Elasticsearch 中,有没有预处理的实现呢?
4、Elasticsearch 数据预处理
Elasticsearch的ETL利器——Ingest节点,已经将节点角色划分、Ingest 节点作用,Ingest 实践、Ingest 和 logstash 预处理优缺点对比都做了解读。有相关盲点的同学,可以移步过去过一遍知识点。
Ingest 节点的本质——在实际文档建立索引之前,使用 Ingest 节点对文档进行预处理。Ingest 节点拦截批量索引和单个索引请求,应用转换,然后将文档传递回单个索引或批量索引API 写入数据。
下面这张图,比较形象的说明的 Elasticsearch 数据预处理的流程。
实际业务场景中,预处理步骤如下:
-
步骤1:定义 Pipeline,通过 Pipeline 实现数据预处理。
根据实际要处理的复杂数据的特点,有针对性的设置1个或者多个 pipeline (管道),上图的粉红和黄色部分。
-
步骤2:写入数据关联Pipeline。
写入数据、更新数据或者 reindex 索引环节,指定要处理索引的 pipeline , 实际就是写入索引与上面的 pipeline0 和 pipelineZ 关联起来。
-
步骤3:写入数据。
划重点:Ingest 实现在实际文档编制索引(索引化)之前对文档进行预处理。
5、实践一把
5.1 线上问题 1 实现
PUT _ingest/pipeline/split_id
{
"processors": [
{
"script": {
"lang": "painless",
"source": "ctx.myid_prefix = ctx.myid.substring(0,2)"
}
}
]
}
借助 script 处理器中的 substring 提取子串,构造新的前缀串字段,用于分析环节的聚合操作。
5.2 线上问题 2 实现
PUT _ingest/pipeline/json_builder
{
"processors": [
{
"json": {
"field": "headers.userInfo",
"target_field": "headers.userInfo.target"
}
}
]
}
借助 json 处理器做字段类型转换,字符串转成了 json。
5.3 线上问题3 实现
PUT _ingest/pipeline/add_builder
{
"processors": [
{
"script": {
"lang": "painless",
"source": """
for (int i=0; i < ctx.tag.length;i++) {
ctx.tag[i]=ctx.tag[i]+"2";
}
"""
}
}
]
}
借助 script 处理器,循环遍历数组,实现了每个数组字段内容的再填充。
篇幅原因,更详细解读参见:
https://github.com/mingyitianxia/deep_elasticsearch/blob/master/es_dsl_study/1.ingest_dsl.md
6、不预处理 VS 预处理后写入方案对比
「方案 1」:数据原样导入Elasticsearch,分析阶段再做 painless 脚本处理。简单粗暴。
导入一时爽,处理费大劲!
如前所述,script 处理能力有限,且由于 script 徒增性能问题烦恼。
不推荐使用。
「方案 2」:提前借助 Ingest 节点实现数据预处理,做好必要的数据的清洗(ETL) 操作,哪怕增大空间存储(如新增字段),也要以空间换时间,为后续分析环节扫清障碍。
看似写入变得复杂,实则必须。「以空间为分析赢取了时间」。
推荐使用。
7、常见问题
7.1 Ingest 节点是必须设置的吗?
默认情况下,所有节点都默认启用 Ingest,因此任何节点都可以完成数据的预处理任务。
但是,当集群数据量级够大,集群规模够大后,建议拆分节点角色,和独立主节点、独立协调节点一样,设置独立专用的 Ingest 节点。
7.2 pipeline 什么时候指定呢?
创建索引、创建模板、更新索引、reindex 以及 update_by_query 环节 都可以指定 pipeline。
7.2.1 创建索引环节指定 pipeline
PUT ms-test
{
"settings": {
"index.default_pipeline": "init_pipeline"
}
}
7.2.2 创建模板环节指定 pipeline
PUT _template/template_1
{
"index_patterns": ["te*", "bar*"],
"settings": {
"number_of_shards": 1,
"index.default_pipeline":"add_builder"
}
}
7.2.3 更新索引环节指定pipeline(原索引未指定)
PUT /my_index/_settings
{
"index" : {
"default_pipeline" : "my_pipeline"
}
}
7.2.4 reindex 环节添加 pipeline
POST _reindex
{
"source": {
"index": "source"
},
"dest": {
"index": "dest",
"pipeline": "some_ingest_pipeline"
}
}
7.2.5 update 环节指定pipeline
POST twitter/_update_by_query?pipeline=set-foo
上述内容就是Elasticsearch 预处理的技巧示例分析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/148966.html