先把话说在前面ElasticSearch的项目我做过不少但真正让人头疼的从来不是集群调优或者复杂查询而是最基础的数据管理。索引映射设计得稀烂、分词器选错、mapping里塞了一堆用不上的字段这些坑一旦埋下后面再想回头改代价高到你想删库重来。这篇东西不聊虚的就围绕ElasticSearch基础数据管理从核心概念到建模最佳实践把我觉得最值得记住的东西捋一遍。适合刚上手ES的开发者也适合那些已经写了不少DSL、但没系统梳理过数据建模思路的人。1. 数据管理先搞懂这层底子文档、索引、映射到底怎么回事1.1 文档和索引的关系别再用数据库那套逻辑硬套很多人第一次接触ES下意识就会拿它跟MySQL做类比索引对应表文档对应行字段对应列。这个类比能帮你快速入门但如果你真照着关系型数据库的思路去设计ES的数据模型后面大概率要吃苦头。ES里的索引Index其实是一个逻辑命名空间它把一组具有相同特征的文档归拢在一起。每个文档Document是JSON对象以倒排索引为核心结构存储。这里的核心区别在于关系型数据库是先有表结构再往里填数据数据必须严格符合预定义的模式而ES的索引在默认情况下是允许字段“动态映射”的插入一条文档时如果某个字段预先没定义过ES会根据字段值自动推断类型并加入映射。我用一个实际场景说明这个差异。假设你要存订单数据MySQL里你得先建好orders表定义好order_id、user_id、amount这些列再插入数据。ES里如果你图省事直接POST一条包含新字段的文档进去索引的mapping会自动增加这个字段。看起来方便实际上埋了雷不同文档里同一个字段如果出现了不同类型比如一条是字符串、另一条是数字ES的动态映射会让这个字段变成“既是text又是keyword”或者直接映射失败后面查询和排序会出各种莫名其妙的问题。所以我的建议是开发环境可以用动态映射快速验证生产环境一定要关闭dynamic mapping或者至少设置成dynamic为false新字段忽略不索引或strict新字段直接报错。宁可在写入前多花几分钟设计好映射也别让ES自作主张。1.2 映射Mapping是数据管理的灵魂映射在ES里就是字段级别的schema定义它决定了每个字段怎么被索引、怎么被存储、怎么参与查询和聚合。映射设计得好不好直接影响索引的写入速度、存储占用和查询性能。映射里最核心的几个部分是字段类型、分词器、doc_values、norms、index选项。字段类型决定了这个字段是走全文搜索text还是精确匹配/聚合keyword是存数字long/double/integer还是存地理位置geo_point。分词器决定了一段文本怎么被切分成词项比如“ElasticSearch基础数据管理”用标准分词器会切成“elasticsearch”“基础”“数据”“管理”用IK分词器在中文场景下切词可能不完全一样。doc_values是列式存储用于排序和聚合text字段默认不支持doc_valueskeyword字段默认支持。norms是归一化因子用于计算相关性分数如果你确定某个字段永远不会用来算相关度可以把norms关掉节省空间。每个字段都可以单独设置这些属性。比如一个状态字段既想用来做精确过滤又想在结果里展示那用keyword类型就够用。但如果你还希望根据状态描述做模糊搜索那就得单独搞一个text类型的字段配合不同的分词器。注意mapping一旦创建字段类型就不可修改。ES官方给了reindex方案来重建索引但reindex意味着你要把数据重新写一遍数据量大得时候代价很高。所以在设计阶段就把字段类型定准确比事后补救划算得多。1.3 分片和副本决定了数据分布与冗余分片Shard是ES数据分布的最小单位副本Replica是分片的冗余拷贝。一个索引在创建时可以指定主分片数和副本数比如3个主分片、1个副本意味着索引数据会被拆成3份分布在节点上同时每份都有一份拷贝总共6个分片3主3副。这里有个常见误解主分片数能不能后期调整不能。主分片数在索引创建后就固定了除非reindex到一个新索引否则无法修改。这也是为什么很多人在创建索引前会纠结分片数。分片数设多少合适我从实际操作角度给一个参考单个分片的数据量控制在30GB到50GB之间比较合适具体还要看节点数、查询复杂度、磁盘性能。不是分片越多越好分片太多会导致每个分片都很小请求分发开销变大全局聚合时结果合并的代价也高分片太少单分片数据量过大会拖慢查询和写入。副本数倒是可以随时调整副本多能提升查询吞吐量但也占磁盘和内存。数据管理的底层逻辑就是索引是逻辑容器分片是物理分布单元映射是字段规则文档是实际数据。把它们之间的关系理清楚后面所有操作都有了正确的前提。2. 字段类型与分词器怎么选映射设计的核心决策点2.1 text和keyword别选错字段类型选择是映射设计里最容易出错的地方。text类型会对内容做全文分析把原始文本分词、转小写、过滤停用词后建立倒排索引适合做模糊检索、相关性排序。keyword类型不分析整段内容作为一个词项存储适合做精确匹配、term查询、聚合、排序。一个典型的错误是把订单号、手机号、用户名、标签这类字段设为text。订单号里可能包含特殊符号text类型会把它拆得乱七八糟term查询根本匹配不上更可怕的是text字段默认不能做聚合fielddata默认关闭打开会吃大量堆内存。反过来如果你把文章正文设为keyword那整篇文章只能做精确匹配完全没法搜索。实际项目中我倾向于用multi-fields多字段方案——同一个字段既保留keyword类型用于精确匹配和聚合又保留text类型用于全文检索。示例如下{ mappings: { properties: { title: { type: text, fields: { keyword: { type: keyword, ignore_above: 256 } } } } } }这样对title做全文搜索时用title做排序或聚合时用title.keyword。代价是多占用一些存储空间但换来的是极大的灵活性我个人认为在绝大多数业务场景里是值得的。2.2 分词器决定搜索效果别直接用默认值对付中文ES自带的标准分词器对英文支持不错对中文就差强人意了。它会按单字切分或者简单的二元切分搜“数据分析”可能搜出来一堆包含“数据”或“分析”的结果相关度排序一塌糊涂。中文场景下用IK分词器ik_max_word做最细粒度切分ik_smart做粗粒度切分是主流方案。我举个具体例子有个搜索需求是根据商品名称搜索商品商品名叫“男士商务休闲衬衫”。用ik_max_word会切成“男士”“商务”“休闲”“衬衫”“商务休闲”“休闲衬衫”等召回率高用ik_smart会切成“男士”“商务休闲衬衫”更精准但可能遗漏带“休闲衬衫”的文档。实际项目里常用ik_max_word建索引搜索时用ik_smart或者两边都用ik_max_word来保证召回率。分词器的选择还涉及到自定义词库。业务里有大量专有名词时比如公司内部的项目代号、产品型号默认词库根本认不出来。ES支持在IK分词器的配置目录里维护自定义词库把专有名词加进去这样分词才能正确切分。这个工作必须在建索引前做好因为分词器是mapping里的固定配置。2.3 数值、日期和布尔类型精确映射比省事重要数值类型在ES里分为long、integer、short、byte、double、float、half_float、scaled_float。不要贪图省事全用long比如年龄用byte就够金额用scaled_float可以通过缩放因子避免浮点精度问题。日期类型date在ES里底层存储为long型时间戳但可以接受多种输入格式比如“2024-01-01”“2024/01/01 12:00:00”映射时需要指定format。布尔类型boolean很简单但要注意ES里布尔值的写法是true/false不要写成1/0。日期字段有个细节特别值得注意如果你需要按天做聚合统计把时间字段映射为date类型并指定format为“yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||strict_date_optional_time”后面对时间范围查询和date_histogram聚合都会方便很多。如果存成字符串后面就等着写一堆恶心的脚本处理吧。2.4 动态映射图省事的代价前面提到了dynamic mapping这里展开说一下。动态映射可以自动为新字段推断类型规则大致是字符串默认映射为text加keyword子字段整数映射为long浮点数映射为float日期格式的字符串映射为date。听起来很方便但在生产环境里这个特性十有八九是灾难。有一次我排查一个线上问题某个索引的数据量并不大但查询慢得离谱。后来发现有人往里写了大量带有随机字段的文档每个文档都产生几十个新字段映射里多出来几千个字段每个新字段都额外占用了倒排索引和doc_values空间索引膨胀好几倍。从那以后我建索引默认都设dynamic为false再配合严格的写入端校验宁可写入失败也不让脏字段进来。3. 索引建模的最佳实践从字段设计到分片规划3.1 字段冗余该冗余的就冗余别搞连表查询ES没有真正意义上的join查询。虽然它提供了nested和join数据类型来模拟关联关系但这两种方案在性能和使用方便程度上都远不如关系型数据库。与其在ES里做父子关联不如在写入前就把需要展示和检索的字段冗余到文档里。以订单为例如果搜索页面需要展示商品名称、店铺名称、用户昵称那在设计ES索引时最好把商品名、店铺名、用户名直接冗余到订单文档里而不是存一个商品ID然后在应用层去查商品库再拼装数据。查询时一个GET就能拿到全部展示所需字段应用层不需要二次查询。虽然冗余会带来数据一致性的维护成本但在ES的分布式架构下这是用空间换查询性能的必经之路。3.2 嵌套类型与父子关系慎用但用对有些业务确实需要保留对象之间的关联关系比如一篇博客有多个评论评论又要按时间排序和过滤。这种情况下有两种方案。第一种是nested类型它把一组对象作为独立索引单元存储查询时可以保证对象之间的独立性。普通object类型在文档里会被扁平化比如用户地址里的“城市”和公司地址里的“城市”会混在一起nested可以避免这个问题。代价是查询时需要用nested查询语法而且nested对象在底层是独立文档写入和查询都有额外开销。第二种是join类型它允许在同一个索引里定义父子文档关系。但join类型极其消耗资源父文档和子文档要维护特殊的全局序数写入和查询性能都受到明显影响。我的个人经验是能冗余解决的就冗余能用nested的就用nestedjoin类型除非万不得已不要碰。如果业务确实需要频繁变更关联关系那说明这个场景更适合用关系型数据库而不是硬要用ES。3.3 分片数量前期规划的计算思路分片规划没有绝对标准但可以按这个思路算。先预估单索引的数据量比如每天新增5GB数据保留30天总数据量150GB。然后预估每个分片合适的数据量我给个保守区间单分片30GB到50GB。150GB除以40GB大约4个分片。如果集群有3个数据节点主分片数可以设为3或6方便均匀分布副本数设为1。这只是个估算思路实际还要考虑查询压力。如果查询并发很高每个分片都参与查询分片多一些能提高并行度如果主要是写入密集分片少一些反而能减少写入放大。关键陷阱主分片数创建后就不能修改所以创建索引前一定要想清楚。我见过有人把主分片数设为1数据量到后期涨到几百GB单分片扛不住只能reindex。同样地把分片数设成几十个、每片只有几GB的人我也见过查询性能并不理想因为协调节点合并分片结果的开销被放大了。3.4 别忽视字段级参数的存储收益同样是keyword字段不同的字段级设置会带来显著的存储差异。ignore_above参数可以限制最长索引长度比如ignore_above设置为256超过256个字符的keyword字段就不会被索引只保留在_source里。norms可以关闭节省每个文档的归一化因子存储。doc_values如果该字段从不用于排序和聚合可以关闭但关闭后就无法用该字段做sort、agg和script操作谨慎使用。这些年我在生产环境里做过多次索引瘦身印象最深的一次是把日志类索引里几个超长message字段的norms关掉、ignore_above调低再配合_source的过滤includes/excludes只保留必要字段索引体积直接降了差不多三分之一。这些操作都不复杂收益却很直接属于投入产出比最高的优化之一。4. 数据写入与更新机制原理、细节与坑4.1 refresh、translog与flush写入链路三节点ES写入一条文档流程大致是这样的请求到达主分片写入内存buffer同时写入translog日志。内存buffer默认每秒refresh一次refresh后生成新的segment这时文档才能被搜索到。translog是防止数据丢失的机制默认每次写请求后fsync一次保证节点宕机后可以恢复。flush是translog被落盘、segment被合并的过程默认30分钟或translog达到512MB触发一次。我见过不少初学者困惑为什么刚写入的数据查不到答案就在refresh机制里。ES的近实时搜索靠的就是refresh间隔。如果你需要写入后立即可见可以把refresh_interval设为1s默认就是这个或者写入后手动调用refresh接口。但生产环境如果写入压力大频繁refresh会拖慢写入速度这时可以把refresh_interval调大比如5s甚至30s牺牲可见性换取写入性能。translog也有个容易踩的坑。很多人以为translog只在节点宕机时有价值平时无所谓于是把index.translog.durability设为async期望提升写入性能。这种做法确实能提升写入吞吐但代价是节点宕机时可能丢失最近几秒的数据。对日志类非关键数据可以接受对订单、交易这类关键数据我建议保持默认的request配置别为了压测好看而牺牲数据可靠性。4.2 更新和删除ES里没有真正的原地修改ES文档是不可变的更新和删除本质上是标记新写入。更新一条文档实际是将旧文档标记为删除再写入一条新文档旧文档等到segment合并时才被真正清理。删除同理只是写入一个tombstone标记。这就是为什么ES的文档删除不会立即释放磁盘空间。这个机制带来的直接后果是频繁更新文档会产生大量旧版本数据磁盘占用会超出你想象。有一个场景我印象很深某个业务系统里每条订单每天要更新好几次状态一年下来索引体积是原始数据量的好几倍。后来我们调整了数据模型把可变状态单独建一个索引主文档尽量少更新才把问题解决。ES的update操作还涉及到版本控制。默认情况下更新需要带上正确的版本号或者用内部版本号做乐观锁控制防止并发更新导致的数据覆盖。用外部版本号external version进行更新时可以自己控制版本值适合从其他数据库同步数据的场景。4.3 bulk批量写入的正确姿势用bulk接口批量写入是ES写入性能的关键。一次bulk请求可以包含多个index/create/update/delete操作大幅减少网络往返次数。但bulk不是越大越好请求体过大容易导致内存压力和执行超时。我从实践中给出的经验值单个bulk请求控制在5MB到15MB之间比较稳妥或者按条数控制每批1000到5000条。具体还要结合数据字段大小来调整。数据量大的时候建议先用小批量压测看响应时间和写入速率再逐步加大找到吞吐曲线的拐点。bulk还有一个经常被忽略的细节批量请求中部分文档失败时返回结果里每个子操作都有独立的status码。你需要在应用层检查每个item的status而不是只看整体HTTP响应码。我有一次批量导入时整体响应是200但里面上千条文档因为数据格式问题全部失败应用层没仔细检查结果导了大半天数据才发现一条都没写进去。4.4 写入端数据校验别让脏数据进门数据校验应该放在写入之前。ES的mapping虽然能做一部分类型校验但业务级别的校验比如必填字段、字段取值范围、枚举值合法性ES不管。我在实际项目中习惯在写入侧加一层校验逻辑字段缺失、类型不对、格式不合法的数据在进入ES之前就被拦下来。具体做法不复杂先定义一个字段配置清单包含字段名、类型、是否必填、取值范围、格式校验规则然后在写入ES前用校验器逐字段检查。对失败的数据要么丢弃并记日志要么进入死信队列人工处理。这么做的好处是ES中的数据始终保持干净查询和聚合的结果才可信。数据管理这件事脏数据进来容易清洗出去难防胜于治。5. 查询与性能调优数据管理的一部分5.1 filter和query要分清ES查询分为两类上下文query上下文和filter上下文。query会计算相关性分数影响排序结果比如match查询就是query上下文filter只判断是否匹配不计算分数但结果会被缓存比如term、range、exists等查询放在filter上下文中会走查询缓存性能远高于query。实际开发中能过滤的尽量用filter。举个例子搜索“价格在100到500之间的商品”价格范围的range查询适合放filter商品的match搜索放query。这么一拆filter部分的结果可以被ES缓存下次同样的查询直接命中缓存性能提升非常明显。有些DSL写法会把所有条件都塞进must里ES就得为每个文档计算相关性分数白白消耗CPU。任何不需要参与相关度排序的条件都应该移到filter里。这个优化不需要改数据模型只改查询写法却经常能带来成倍的性能收益。5.2 聚合查询的内存陷阱ES的聚合操作默认使用fielddata内存缓存特别是对大基数keyword字段做terms聚合时ES需要把每个字段值的全局序数加载到内存。如果对text字段做聚合还会触发fielddata的构建这个操作非常吃力不讨好所以text字段默认是禁止聚合的。我在真实项目里就踩过这个坑。一个日志索引想统计每个请求路径的访问量直接对路径字段做terms聚合结果内存直接飙到堆上限频繁触发GC查询响应时间长了十倍。后来排查发现路径字段被映射成了text类型。解决办法是把路径字段加一个keyword子字段用子字段做聚合问题立刻解决。聚合查询还需要注意数据量问题。系统默认限制只返回前10个桶如果你需要更多得设置size。但size设置得太大内存压力也会成倍增加。做高基数聚合时比如几百万个不同值的字段建议用composite聚合做分页遍历而不是一次性取全量桶。5.3 别名、滚动索引与数据生命周期索引别名alias是一个指向一个或多个索引的虚拟名称。别名最大的价值在于应用层只访问别名底层索引变更不影响应用。索引需要升级mapping、拆分或合并时只需要重新指向别名指向的索引应用层无感知。滚动索引用得更多日志类数据非常适合用时间序列索引加别名的方式管理。比如按天创建索引access-2024.01.01、access-2024.01.02然后创建一个别名access指向最近7天的索引每天凌晨把别名往前滚一天旧的索引自动从别名里移除。过期数据的清理也方便直接删掉对应的索引即可不用在索引内部做复杂的删除操作。ELK生态里的ILM索引生命周期管理是更自动化的方案可以把索引按hot/warm/cold/delete几个阶段管理自动完成滚动、迁移和删除。如果集群版本支持生产环境强烈建议用ILM管理时间序列索引省心且不会出错。6. 常见问题与排查技巧实录6.1 症状写入报错“Rejecting mapping update”这个报错的意思是文档里出现了mapping中未定义的字段同时mapping的dynamic被设置为false或strict。排查思路很简单先看mapping定义确认字段是否在映射里再看dynamic设置最后看写入的JSON里有哪些字段是新增的。解决措施通常是在写入侧增加字段白名单校验或者对mapping做更新新增字段对已有mapping不会有影响可以动态加上。但如果是已有字段类型不匹配mapping更新就会失败只能重建索引。6.2 症状查询突然变慢集群CPU飙高优先查这几点一是是否有深分页fromsize过大深分页需要取回并排序大量数据非常费资源二是是否存在无filter的query大范围匹配三是聚合查询是否对大基数字段做了高开销操作四是是否存在字段映射错误比如把keyword字段查成了text。这类问题的排查顺序是先看热门查询DSL再看字段映射最后看集群监控曲线。我在真实项目里遇到过一次最诡异的情况某个索引单条查询只要几毫秒但并发上来就超时。后来发现是查询里把用户输入的字符串直接拼进了wildcard查询相当于对全索引做了一次正则扫描。正确处理方式是把用户输入转成精确term或match查询绝不使用以通配符开头的wildcard。6.3 症状磁盘空间被占满删除数据后不释放还记得前面说的“删除是标记不是物理删除”吗删除文档和更新文档都不会立刻释放磁盘。要释放空间有两种办法一是强制合并segment调用forcemerge API将segment合并为一个或多个同时清理删除标记二是重建索引reindex一份只包含有效数据的新索引然后切别名。forcemerge对在线索引有性能影响会占用大量IO和CPU建议在业务低峰期操作。还有一种情况是索引里存在大量doc_values但从未被使用这类冗余数据只能靠重建索引来去掉平时设计映射时就应该想清楚哪些字段需要doc_values。6.4 症状mapping后期发现字段类型错了怎么办这是最让人崩溃的问题之一。比如当时把价格字段设成了keyword后面想做数值范围查询发现完全不行。最直接的解法是创建新索引定义好正确的mapping用reindex把数据迁移过去再切换别名。数据量大时reindex要跑很久建议在低峰期操作并用scroll或reindex API自带的slice功能做并行迁移。有一种临时方案是用runtime字段在查询时动态定义字段类型和取值逻辑不需要改mapping。但runtime字段没有倒排索引查询性能比正常字段差很多只能作为应急方案不适合长期依赖。7. 数据分析与建模流程一套可以抄作业的步骤7.1 先问业务问题再谈技术选型拿到一个新数据接入需求我的习惯是先列业务问题清单这个数据将来怎么查查询基于哪些条件结果需要展示哪些字段是否需要聚合统计数据更新频率是多少数据保留多久把这些问题逐条回答完ES的数据模型其实就基本成型了。比如要接入一批商品数据业务方说要支持按名称搜索、按分类筛选、按价格区间过滤、按销量排序、按品牌聚合。这些需求直接对应了字段映射决策名称字段用textkeyword多字段分类和品牌用keyword价格用scaled_float或long销量用integer。不需要额外想到的字段一律不冗余进来。7.2 字段清单一步步推演设计mapping前先建立一份字段清单表格对每个字段明确下列属性字段名、业务含义、数据类型、分词策略、是否参与聚合、是否参与排序、是否展示在搜索结果里、是否支持从_source中移除。这个表格就是mapping设计的底稿直接照着转换成JSON即可。我在写mapping JSON时还会顺手注释每个字段的业务含义方便后来的人接手。ES的mapping JSON本身不支持注释但我会在配置管理文档里记录或者在字段名上用自解释的命名方式比如user_id、order_status、created_at这种一眼能看懂的名字。7.3 原型数据验证建索引前先跑一版探路正式建索引前我会先用一小批真实数据做原型验证创建临时索引写入样本数据用几组典型的查询语句测试搜索效果和响应时间确认结果符合预期后再迁移到正式索引。这一步能提前发现分词器选择不合适、字段类型映射不对、查询语法写错等问题比直接在线上环境折腾要稳妥得多。原型验证时特别要注意测试查询的覆盖度精确匹配、模糊匹配、范围过滤、排序、聚合、高亮、分页都要覆盖到。任何一个环节出问题回头的成本都很高所以这步做扎实是最划算的投资。7.4 上线后的数据治理机制上线只是开始。数据管理要长期运转必须建立几个机制一是mapping变更流程任何新增字段都要经过评估后再上线二是数据质量监控定期检查索引中文档的字段完整性和类型正确性三是索引生命周期管理对时间序列索引做好滚动、备份和过期清理四是查询性能巡检定期查看慢查询日志和热点查询发现异常及时优化。我见过太多项目上线后从不关注数据管理半年后索引膨胀得吓人查询慢到影响业务才不得不花大代价做瘦身和重建。数据管理不是一次性的设计工作它是持续运营的一部分谁在这方面偷懒后面就等着加班补课。8. 几个容易忽略但很有用的实战细节8.1 _source字段要能找回来但别什么都存_source是写入时的原始JSON文档ES默认存储它用途是在搜索结果里直接返回完整文档。它支持includes/excludes过滤可以只存部分字段。关掉_source可以显著降低存储占用但代价是update、reindex、painless script等依赖_source的操作都会失效。我的建议是保留_source但把大字段日志详情、请求体等排除掉。这种场景适合把大字段抽到单独的存储系统比如对象存储ES里只保留索引和元信息。_source的过滤在创建mapping时就可以配置不需要在写入端做额外处理。8.2 用模板统一管理索引配置索引模板Index Template可以预定义索引的mapping、setting、别名匹配到特定模式时自动生效。比如定义一个access-*的索引模板所有以access-开头的索引创建时都会自动套用这个模板。这对每天滚动生成的日志索引特别方便不需要每次创建索引都手工配置一遍。模板的优先级要注意索引创建时手工指定的设置优先级高于模板模板之间也可以按order字段设置优先级。我习惯把通用设置分片数、副本数、refresh间隔、分词器配置放在基础模板里把字段映射放在更具体的高优先级模板里管理起来清晰很多。8.3 字段命名一致性也影响效率ES字段命名虽然没有强制规范但一套一致的命名习惯能大幅减少认知成本。我的习惯是全部小写、单词间用下划线分隔、布尔类型用is_开头、日期类型以_at结尾、ID类字段以_id结尾。这样做的好处是不同索引之间字段含义不容易混淆排查问题时看字段名就能猜出个大概跨团队协作时也不需要每次翻mapping文档。9. 数据管理实操总结与个人体会做ElasticSearch数据管理这些年我最深的体会是绝大多数的“坑”都不是ES本身的缺陷而是在设计阶段没有想清楚数据会被如何使用。mapping设计、字段类型选择、分词器配置、分片规划这些在项目初期的决定会一路影响到系统运行很久之后改起来的代价远超想象。如果你刚接触ES我建议不要急着写DSL先花时间把索引的mapping设计、写入链路原理和查询上下文差别吃透。这些基础的东西掌握扎实了后面处理问题时会顺手很多。我自己后来每次新建索引都会强迫自己先回答几个问题这个索引的数据量级大概是多少查询模式有哪些哪些字段需要全文搜索哪些字段只需要精确匹配数据更新频率高不高把这些想明白再动手写mapping基本不会出大问题。最后分享一个小技巧可以在Kibana里用Console保存一套自己常用的索引mapping模板每次新建索引时复制出来修改即可。我自己的模板包含日志类、业务数据类、文档检索类三种覆盖了大部分场景省了不少重复工作。数据和索引毕竟是要长期伺候的“活物”前期多想一步后面省心十步。
阅读完成 · 觉得有帮助?