ES服务器中“显示的列”本质上不是索引层面的固定配置,而是在查询结果或可视化界面中,通过_source字段过滤、fields参数以及Kibana索引模式来完成设置的。很多刚接触Elasticsearch的朋友会把传统数据库的“列”概念直接套过来,结果在Kibana里翻半天找不到“设置列”的按钮,接下来我会把三个不同场景下的列显示设置方法一次讲透,覆盖实际运维中最常用的操作路径。
搞清ES中“列”的真实身份:字段与_source
在动手设置之前,先厘清一个关键认知:ES底层存储的是JSON文档,它没有严格意义上的“列”,只有字段(Field),我们在Kibana或API返回结果中看到的“列”,其实是文档中字段的投影。
传统MySQL里,列是表的固有属性,增删列需要走DDL,而ES中,每个文档的_source字段自动存储了索引时发送的原始JSON,查询时默认原样返回。你看到的每一列,就是_source里的一个键值对,这个机制决定了“设置显示列”这件事,主要是在查询阶段做字段裁剪,而不是在存储阶段做结构变更。
搞清楚这一点后,下面分场景逐个击破。
通过REST API查询时,只返回指定字段
如果你不是用Kibana,而是直接调ES的_search接口(比如在脚本或Postman里调试),控制返回列有两种主流写法。
使用_source参数裁剪字段
这是最常见的方式,在查询请求体里加上_source,既可以指定包含哪些字段,也可以排除哪些字段。
{
"_source": {
"includes": [ "title", "price", "create_time" ]
},
"query": { "match_all": {} }
}
执行后,返回的每个文档_source里就只有title、price、create_time这三列了,如果你想让省略写法更简洁,可以直接用数组形式:
{
"_source": ["title", "price"],
"query": { "match_all": {} }
}
需要排除某些字段时,用excludes:
{
"_source": {
"excludes": [ "internal_code", "remarks" ]
}
}
这里有个细节容易踩坑:_source过滤是在获取文档之后才进行的,所以它只影响网络传输和展示体积,不会减少ES内部读取索引的开销,如果文档特别大且访问量很高,更优的做法是在存储阶段关闭_source或者使用source filtering配合docvalue_fields。
使用fields参数获取特定字段值
从ES 7.x开始,官方更推荐使用fields参数(注意不是docvalue_fields),它支持通过format参数指定日期格式,还能从_source和doc_values中综合取值,是比_source更灵活的方式。
{
"fields": ["title", "price"],
"_source": false,
"query": { "match_all": {} }
}
加上"_source": false后,返回结果中不再显示原始文档,而是只显示fields里指定的列,需要格式化日期时,可以这样:
{
"fields": [
{ "field": "create_time", "format": "yyyy-MM-dd" },
],
"_source": false,
"query": { "match_all": {} }
}
业界惯例是:如果要拿完整文档原文做展示,用_source过滤;如果只关心少量字段的值或需要格式化输出,优先用fields。
Kibana Discover页面中如何调整显示列
日常排查日志或分析数据时,我们大部分时间泡在Kibana的Discover页面,这里设置显示列的操作路径很直观,但我见过不少人在索引模式里绕圈子。
第一步:确保索引模式字段正确
进入Kibana后,通过Stack Management → Index Patterns找到你正在使用的索引模式,Discover页面显示的每一列,都来自这个索引模式中已存在的字段,如果ES里加了新字段但Discover里看不到,点击索引模式详情页右上角的刷新按钮,同步最新字段映射。
第二步:在Discover里直接增删列
操作步骤如下:
- 打开Discover页面,选好索引模式和时间范围。
- 在左侧“Available Fields”列表中,鼠标悬停在想要的字段上,点击旁边的“add”按钮(或直接点击字段名),该字段就会成为表格中的一列。
- 想移除某列,点击表格顶部的字段名,在弹出的下拉菜单中选择“Remove column”。
- 列的顺序可以拖动表格标题栏调整。
第三步:保存视图,一劳永逸
调整好列后,记得点击Discover工具栏上的“Save”按钮,给这个视图起个名字(nginx错误日志关键列”),下次直接打开这个已保存的搜索,列设置就自动加载了。
行业共识认为,Kibana索引模式中的字段格式设置(如日期格式、IP类型)会直接影响列显示效果,如果某列显示成“-”或者乱码,先去索引模式里检查该字段的格式是否匹配。
聚合分析中控制返回列(Metric/TSVB)
如果你在用Kibana的TSVB视觉图(Time Series Visual Builder)或Vega做监控大盘,同样有“列”的概念。
在TSVB的Panel options里,有个“Data”配置项,可以指定“Fields”来设置表格的展示列,开发模式下,可以直接编辑series的metrics与group by字段来实现列控制。
我用TSVB排查ES集群写入性能时,一般这样操作:
- 选择聚合方式:
Average、Max等。 - 在“Field”下拉框里选择需要展示的指标字段(比如
indexing_index_total)。 - 在“Group by”里选择
Terms,并按host.name分组,这样表格里就会按主机名一列一列展示指标。
TSVB这种可视化之上的“列”设置,本质上是在查询阶段通过子聚合动态生成表格列,灵活性很高,但学习成本也高,如果想快速验证效果,推荐先用Discover页面的基础列调整,把字段顺序和格式跑通了再上TSVB。
附加实用技巧:批量查看字段,避免“列爆炸”
生产环境的索引动辄几百个字段,手把手在Discover里一列一列加太慢,这里分享两个高效操作。
用Kibana的“View surrounding documents”
在Discover的表格视图下,点击任意文档左侧的展开箭头,会出现“View surrounding document”按钮,点击后,ES会对比这个文档的前后几条记录,此时你可以通过“Available Fields”勾选自己关心的字段作为临时列,这个操作不需要重新配置索引模式。
控制“doc_table”列的密度
在Stack Management → Advanced Settings里,搜索discover:sampleSize和discover:sampleRowsPerPage,前者控制加载的文档数(默认500),后者控制每页显示的行数,增大数值后,表格里的行数变多,配合加列操作,能一次性看到更多字段的数据分布,快速定位哪些字段值得长期保留。
写脚本时用_source的wildcard通配符
如果一个业务有大量相似字段(比如status_1到status_100),在查询时可以用通配符一次性包含:
{
"_source": { "includes": ["status_"] }
}
这样返回的“列”就是所有以status_开头的字段,简洁高效。
一个副作用:字段过滤对查询性能的影响需要关注
文章开头说过,_source过滤不影响查询匹配,只影响返回内容,但在大集群里,如果同时查询大量字段且每个文档体积很大,网络IO会成为瓶颈,独立来看,各字段的doc_values已经存储在磁盘上,但_source字段是压缩存储的,频繁做source filtering反而会增加CPU负担。
这种情况下,行业内的常规做法是:
- 只对必要的字段设置
store: true,这会把该字段单独存储一份,查询时用stored_fields直接取,不读整个_source。 - 对超大文档(比如二进制base64字段),从设计上就将其拆到独立索引,避免主查询时“扛上”无用的列。
常见误区与避坑指南
认为“删除列”能释放存储空间
ES中,_source过滤或Kibana移除列,都不影响索引底层数据,文档依旧原样存储在Lucene中,真正想节省存储,得靠索引映射(Mapping)中设置"_source": {"enabled": false},或者用ingest pipeline在写入时剥离字段。但关闭_source会带来聚合、更新部分字段时的功能损失,骨灰级玩家才建议这么干。
混淆“别名”和“列显示”
有些同学在索引模式里给字段增加了alias(别名),然后在Discover里看到列名变了,以为这就是设置了显示的列,列显示是视图层的,而alias是字段映射层的,它是只读的,无法用来过滤查询,仅作展示。
忘了刷新字段列表导致列找不到
这种情况非常常见,尤其是日志类索引每天自动滚动创建时,新索引里如果有新字段,索引模式里不会自动出现。需要手动刷新索引模式,或者在Kibana的字段列表界面点击“Refresh field list”,然后再去Discover里添加列。
Q&A:围绕ES显示列设置的高频问题
ES查询结果里字段顺序能控制吗?
ES返回的JSON文档中,字段顺序取决于_source里的原始存储顺序,无法像SQL里SELECT col1, col2那样指定输出顺序,如果必须按特定顺序展示,只能在应用层或Kibana的表格配置中手动拖拽列来完成排序。fields参数会按请求体里的顺序返回多字段。
Kibana里Add column按钮是灰色的,列加不进去怎么办?
最常见的原因是当前索引模式没有匹配到任何新文档,先检查时间范围,将时间过滤器调整到包含数据的时间段;再确认索引模式名称与你实际索引的命名空间是否匹配(比如你索引是nginx-access-2026.01.01,但索引模式写的是nginx-access-),排除这两点后,刷新索引模式字段列表,按钮即恢复可用,若仍无效,查看Kibana日志中是否有字段类型冲突(同一个字段映射成了long和text),这种情况在ES 7.x中经常因自动映射引起,需手动修正映射。
ES中列显示设置的核心答案最终可以归结为一句话:API查询用_source过滤,Kibana展示靠索引模式加字段,可视化看板在TSVB的series配置里完成字段裁剪,三者互有分工,但都以字段(而不是列)为操作单元,下次遇到“列不对”或“列太多”的问题,就可以直接从这三个环节去定位解决。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/794885.html


