学会这个ES数据建模指南,还需要啥MySQL?( 四 )


这里给出索引层面Setting设置的简单模板 , 供你进一步学习参考 , 如下定义了indexed_at缺省的管道 , 同时在索引my_index_0001指定了该缺省管道 , 这样做的好处 , 是每个新增的数据都会加了插入时刻的时间戳:indexed_at字段 , 无需我们在业务层面手动处理 , 非常灵活和方便 。
更多设置 , 推荐阅读官方文档 , 地址如下:
https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings
PUT_ingest/pipeline/indexed_at
{
"description":"Addsindexed_attimestamptodocuments",
"processors":[
{
"set":{
"field":"_source.indexed_at",
"value":"{{_ingest.timestamp}}"
}
}
]
}
PUTmy_index_0001
{
"settings":{
"number_of_replicas":1,
"number_of_shards":3,
"refresh_interval":"30s",
"index":{
"default_pipeline":"indexed_at"
}
},
"mappings":{
"properties":{
"cont":{
"type":"text",
"analyzer":"ik_max_word",
"fields":{
"keyword":{
"type":"keyword"
}
}
}
}
}
}
4、基于Mapping层面建模
Mapping层面核心是字段名称、字段类型、分词器选型、多字段multi_fields选型 , 以及字段细节(是否索引、是否存储等)的敲定 。
1)字段命名要规范
索引名称不允许用大写 , 字段名称官方没有限制 , 但是可以参考Java编码规范 。 我还真见过学员用中文或者拼音命名的 , 非常不专业 , 大家一定要避免 。
2)字段类型要合理
要结合业务类型选择合适的字段类型 。 比如integer能搞定的 , 就不要用long、float或double 。
注意 , 字符串类型在5.X版本之后分为两种类型:一种是keyword , 适合精准匹配、排序和聚合操作;另一种是text , 适合全文检索 。 默认值text&keyword组合不见得是最优的 , 选型时候要结合业务选择 。 比如优先选择keyword类型 , keyword走倒排索引更快 。
再举个例子 , 实战中情感值介于0~100之间 , 50代表中性 , 0~50代表负面 , 50~100代表正面 。 如果使用integer查询的时候要rangequery , 而实际存储可以增加字段:0~50设置为-1 , 50设置为0 , 50~100设置为1 , 三种都是keyword类型 , 检索时直接走term检索会非常快 。
3)分词器要灵活
实战中中文分词器用得比较多 , 中文分词又分为ansj , 结巴 , IK等 。 以IK举例 , 可以细分为ik_smart粗粒度分词、ik_max_word细粒度分词 。
在工作中 , 要结合业务选择合适的分词器 , 分词器一旦设定是不可以修改的 , 除非reindex 。
分词器选型后 , 都会有动态词典的更新问题 。 更新的前提是不要仅使用开源插件原生词典 , 而是要在平时业务中自己多积累特定业务数据词典、词库 。
如果要动态更新:一般推荐第三方更新插件借助数据库更新实现 。 如果普通分词都不能满足业务需要 , 可以考虑ngram自定义分词方式实现更细粒度分词 。
4)multi_fields适机使用
同一个字段根据需要可以设置多种类型 。 实战业务中 , 对用特定中文词明明存在 , 却无法召回的情况 , 采用字词混合索引的方式得以满足 。
所谓字词混合 , 实际就是standard分词器实现单字拆解 , 以及ik_max_word实现中文切词结合的方式 。 检索的时候bool对两种分词器结合 , 就可以实现相对精准的召回效果 。
PUTmix_index
{
"mappings":{
"properties":{
"content":{
"type":"text",
"analyzer":"ik_max_word",
"fields":{
"standard":{
"type":"text",
"analyzer":"standard"
},
"keyword":{