最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

[ES] Elasticsearch 数据建模

[复制链接]
跳转到指定楼层
楼主
发表于 2019-7-3 13:35:10 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
数据建模:英文为Data Modeling,为创建数据模型的过程
数据模型(Data Model)


对现实世界进行抽象描述的一种工具和方法
通过抽象的实体及实体之间联系的形式去描述业务规则,从而实现对现实世界的映射
数据建模的过程:


概念分析:确定系统的核心需求和范围边界,设计实现和实体间的关系
逻辑模型:进一步梳理业务需求,确定每个实体的属性、关系和约束等
物理模型:结合具体的数据库产品,在满足业务读写性能等需求的前提下确定最终的定义
ES中的数据建模相关配置
ES是基于Lucene以倒排索引为基础实现的存储体系,不遵循关系型数据库中的范式约定



Mapping字段的相关设置:


Mapping字段属性的设定流程
是何种类型?
字符串类型:需要分词设定为text类型,否则设置为keyword类型
枚举类型:基于性能考虑将其设定为keyword类型,即便该数据为整型(如状态码)
数值类型:尽量选择贴近的类型,比如byte即可表示所有数值时,即选用byte,不要用long
其他类型:比如布尔类型、日期、地理位置数据等


是否需要检索?
完全不需要检索、排序、聚合分析的字段:enable设置为false


不需要检索的字段:index设置为false


需要检索的字段,可以通过如下配置设定需要的存储粒度


index_options: 结合需要设定
norms: 不需要归一化数据时关闭即可
是否需要排序和聚合分析?
不需要排序或者聚合分析功能:


doc_values设定为false
fielddata设定为false


是否需要专门存储当前字段的数据?
store设定为true,即可存储该字段的原始内容(与_source中的不相关)
一般结合_source的enabled设定为false时使用


ES中的数据建模实例
以博客文章blog_index为例说明创建过程:



blog_index的mapping设置如下:
[AppleScript] 纯文本查看 复制代码
PUT blog_index[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]{
  "mappings": {
    "doc":{
      "properties": {
        "title":{
          "type":"text",
          "fields": {
            "keyword":{
              "type": "keyword"
            }
          }
        },
        "publish_date":{
          "type": "date"
        },
        "author":{
          "type": "keyword"
        },
        "abstract":{
          "type": "text"
        },
        "url":{
          "enabled":"false"     #url不需要做搜索,只存储即可
        }
      }
    }
  }
}    
扩展:在上面的基础上,添加内容content字段,mapping应该如何设计?



思考:博客的content内容可能会有几百上千字,但是如果博客换成书,content的内容可能会有几十万字,变的非常的大。这样如果content字段依然默认为text类型:在取原始数据时,是通过_source来获取原始内容的,每一次取_source都会把content内容取出来,如果content过大就会导致_source获取过多的内容,降低性能


mapping设置成如下内容:结合_source的enabled设定为false时设置store为true
[AppleScript] 纯文本查看 复制代码
PUT blog_index[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]{
  "mappings": {
    "doc":{
      "_source": {
        "enabled": false
      },
      "properties": {
        "title":{
          "type":"text",
          "fields": {
            "keyword":{
              "type": "keyword"
            }
          },
          "store": true
        },
        "publish_date":{
          "type": "date",
          "store": true
        },
        "author":{
          "type": "keyword",
          "store": true
        },
        "abstract":{
          "type": "text",
          "store": true
        },
        "aontent":{
          "type":"text",
          "store": true
        },
        "url":{
          "type": "keyword",
          "doc_values":false,
          "norms": false,
          "ignore_above": 100,
          "store": true          
        }        
      }
    }
  }
}      
插入同样的数据对比:






查询高亮显示:
[AppleScript] 纯文本查看 复制代码
GET blog_index/_search[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]{
  "stored_fields": ["title","publish_date","author","abstract","url"], #不获取content字段
  "query": {
    "match": {
      "content": "blog"
    }
  },
  "highlight": {
    "fields": {"content": {}}
  }
} 

Reindex
Reindex指重建所有数据的过程,一般发生在如下情况:


mapping设置变更,比如字段类型变化,分词字典变更等
index设置变更,比如分片数更改等
迁移数据
ES提供了现成的API用于完成该工作:


_update_by_query 在现有索引上重建
_reindex 在其他索引上重建
官方文档:
Reindex API
Update By Query API


_update_by_query
将twitter的所有文档重建一遍
[AppleScript] 纯文本查看 复制代码
POST twitter/_update_by_query?conflicts=proceed[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]#conflicts=proceed:如果遇到版本冲突,覆盖并继续执行
[AppleScript] 纯文本查看 复制代码
POST twitter/_update_by_query[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]{
  "script": {
    "source": "ctx._source.likes++",
    "lang": "painless"
  },
  "query": {
    "term": {
      "user": "kimchy"
    }
  }
}   
#script:更新文档的字段值; query:可以更新部分文档 
_reindex
[AppleScript] 纯文本查看 复制代码
POST _reindex[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}   


POST _reindex
{
  "source": {
    "remote": {
      "host": "http://otherhost:9200",
      "username": "user",
      "password": "pass"
    },
    "index": "source",
    "query": {
      "match": {
        "test": "data"
      }
    }
  },
  "dest": {
    "index": "dest"
  }
} 


Task
数据重建的时间受源索引文档规模的影响,当规模越大时,所需的时间越多,此时需要通过设定url参数wait_for_completion为false来异步执行,ES以task来描述此类执行任务


ES提供了Task API来查看任务的执行进度和相关数据
[AppleScript] 纯文本查看 复制代码
POST blog_index/_update_by_query?conflicts=proceed&wait_for_completion=false[/color][/size][/font]
[font=微软雅黑][size=3][color=#000000]
{
  "task": "q5X8C6RXT1K0d9PrIZOQ7w:3438612"
}   

GET _tasks/q5X8C6RXT1K0d9PrIZOQ7w:3438612 
其他建议
1.对mapping进行版本管理
包含在代码或者以专门的文件进行管理,添加好注释,并加入git等版本管理仓库中方便回顾
为每个增加一个metadata字段,在其中维护一些文档相关的元数据,方便对数据进行管理
[AppleScript] 纯文本查看 复制代码
{
  "metadata":{
    "version":1
  },
  "username":"alfred",
  "job":"engineer"
}           
#mapping版本,可以自行制定,比如每次更新mapping设置后,该version加1


2.防止字段过多
字段过多:难于维护,当字段成百上千时,基本很难有人明确知道每个字段的含义;mapping的信息存储在cluster state里面,过多的字段会导致mapping过大,最终导致更新变慢。


通过设置index.mapping.total_fields.limit可以限定索引中最大字段数,默认为1000
可以通过key/value的方式解决字段过多的问题,但并不完美:



key/value方式缺点:


query语句复杂度飙升,且有一些可能无法实现,比如聚合分析相关的
不利于在kibana中做可视化分析
一般字段过多的原因是由于没有高质量的数据建模导致的,比如dynamic设置为true,考虑拆分多个索引来解决问题。
---------------------
作者:wfs1994
来源:CSDN
原文:https://blog.csdn.net/wfs1994/article/details/80836077  


楼主热帖
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-5-21 00:21

Powered by BI168大数据社区

© 2012-2014 168大数据

快速回复 返回顶部 返回列表