Elasticsearch 和 ClickHouse 都支持丰富的数据类型,但二者的底层存储和查询模型存在本质差异。本节将常用的 Elasticsearch 字段类型映射到对应的 ClickHouse 类型 (如果有) ,并提供相关背景信息以帮助指导迁移。对于没有对应类型的情况,我们也会在注释中提供替代方案或说明。
| Elasticsearch 类型 | ClickHouse 对应项 | 备注 |
|---|---|---|
boolean |
UInt8 或 Bool |
在较新版本中,ClickHouse 支持将 Boolean 作为 UInt8 的别名。 |
keyword |
String |
用于精确匹配过滤、分组和排序。 |
text |
String |
ClickHouse 的全文搜索能力有限;标记化需要借助自定义逻辑,例如将 tokens 与数组函数结合使用。 |
long |
Int64 |
64 位有符号整数。 |
integer |
Int32 |
32 位有符号整数。 |
short |
Int16 |
16 位有符号整数。 |
byte |
Int8 |
8 位有符号整数。 |
unsigned_long |
UInt64 |
64 位无符号整数。 |
double |
Float64 |
64 位浮点数。 |
float |
Float32 |
32 位浮点数。 |
half_float |
Float32 或 BFloat16 |
最接近的对应类型。ClickHouse 没有 16 位浮点类型。ClickHouse 提供 BFloat16,但它不同于 IEEE-754 half-float:half-float 以较小的范围换取更高精度,而 bfloat16 则牺牲精度以获得更大的范围,因此更适合机器学习工作负载。 |
scaled_float |
Decimal(x, y) |
用于存储定点数值。 |
date |
DateTime |
对应秒级精度的日期类型。 |
date_nanos |
DateTime64 |
ClickHouse 可通过 DateTime64(9) 支持纳秒级精度。 |
binary |
String, FixedString(N) |
二进制字段需要进行 base64 解码。 |
ip |
IPv4, IPv6 |
提供原生 IPv4 和 IPv6 类型。 |
object |
Nested, Map, Tuple, JSON |
ClickHouse 可使用 Nested 或 JSON 对类似 JSON 对象的结构进行建模。 |
flattened |
String |
Elasticsearch 中的 flattened 类型会将整个 JSON 对象存储为单个字段,从而无需完整映射即可灵活、无 schema 地访问嵌套键。在 ClickHouse 中,可使用 String 类型实现类似功能,但需要在 materialized view 中完成处理。 |
nested |
Nested |
在用户使用 flatten_nested=0 的前提下,ClickHouse 的 Nested 列可为成组子字段提供类似语义。 |
join |
NA | 没有直接对应的父子关系概念。在 ClickHouse 中通常不需要,因为支持跨表 join。 |
alias |
Alias 列修饰符 |
可通过字段修饰符来支持别名。详见。例如,可对这些别名应用函数:size String ALIAS formatReadableSize(size_bytes) |
range types (*_range) |
Tuple(start, end) 或 Array(T) |
ClickHouse 没有原生 range 类型,但数值范围和日期范围可用 Tuple(start, end) 或 Array 结构表示。对于 IP 范围 (ip_range) ,可将 CIDR 值存储为 String,并使用 isIPAddressInRange() 等函数进行判断。或者,也可以考虑使用基于 ip_trie 的 lookup 字典来实现高效过滤。 |
aggregate_metric_double |
AggregateFunction(...) 和 SimpleAggregateFunction(...) |
使用 aggregate function 状态和 materialized view 对预聚合指标进行建模。所有 aggregation 函数都支持 aggregate states。 |
histogram |
Tuple(Array(Float64), Array(UInt64)) |
可使用数组或自定义 schema 手动表示桶及其计数。 |
annotated-text |
String |
不内置支持实体感知搜索或注解。 |
completion, search_as_you_type |
NA | 没有原生自动补全或建议器引擎。可通过 String 和 search functions 实现类似效果。 |
semantic_text |
NA | 不支持原生语义搜索;请生成嵌入向量并使用向量搜索。 |
token_count |
Int32 |
可在摄取期间手动计算标记数,例如使用 length(tokens()) 函数,或结合 Materialized 列实现。 |
dense_vector |
Array(Float32) |
使用数组存储嵌入向量。 |
sparse_vector |
Map(UInt32, Float32) |
可使用 Map 模拟稀疏向量。不支持原生稀疏向量。 |
rank_feature / rank_features |
Float32, Array(Float32) |
不支持原生的查询时权重提升,但可以在评分逻辑中手动实现。 |
geo_point |
Tuple(Float64, Float64) 或 Point |
使用 (纬度、经度) 的 Tuple。Point 也可作为 ClickHouse 类型使用。 |
geo_shape, shape |
Ring, LineString, MultiLineString, Polygon, MultiPolygon |
原生支持地理形状和空间索引。 |
percolator |
NA | 没有“为查询建立索引”这一概念。请改用标准 SQL + 增量materialized views。 |
version |
String |
ClickHouse 没有原生版本类型。请将版本存储为字符串,并在需要时使用自定义 UDF 函数进行语义化比较。如果需要范围查询,可考虑将其规范化为数值格式。 |
说明
-
数组:在 Elasticsearch 中,所有字段都原生支持数组。在 ClickHouse 中,数组必须显式定义 (例如
Array(String)) ;其优势是可以访问和查询特定位置的元素,例如an_array[1]。 -
多字段:Elasticsearch 允许以多种方式索引同一字段 (例如同时使用
text和keyword) 。在 ClickHouse 中,这种模式必须通过单独的列或视图来建模。 -
Map 和 JSON 类型 - 在 ClickHouse 中,
Map类型通常用于表示动态键值结构,例如resourceAttributes和logAttributes。该类型允许在运行时添加任意键,从而实现灵活的无 schema 摄取——这与 Elasticsearch 中的 JSON 对象在理念上类似。不过,也有一些重要限制需要注意:- 统一的值类型:ClickHouse 的
Map列必须具有一致的值类型 (例如Map(String, String)) 。如果不进行强制类型转换,则不支持混合类型的值。 - 性能开销:访问
Map中的任意键,都需要将整个 map 加载到内存中,这对性能而言可能并不理想。 - 不支持子列:与 JSON 不同,
Map中的键不会表示为真正的子列,这限制了 ClickHouse 高效进行索引、压缩和查询的能力。
由于这些限制,ClickStack 正在逐步弃用
Map,转而采用 ClickHouse 增强后的JSON类型。JSON类型弥补了Map的许多不足:-
真正的列式存储:每个 JSON 路径都会存储为一个子列,从而实现高效的压缩、过滤和向量化查询执行。
-
支持混合类型:不同的数据类型 (例如整数、字符串、数组) 可以在同一路径下共存,而无需强制转换或类型统一。
-
文件系统可扩展性:对动态键 (
max_dynamic_paths) 和类型 (max_dynamic_types) 的内部限制,即使在高基数键集合的情况下,也能防止磁盘上的列文件数量激增。 -
紧凑存储:NULL 和缺失值会以稀疏方式存储,以避免不必要的开销。
JSON类型尤其适合可观测性工作负载,既具备无 schema 摄取的灵活性,又拥有 ClickHouse 原生类型的性能和可扩展性——因此,它是动态属性字段中替代Map的理想选择。如需进一步了解 JSON 类型,我们建议阅读 JSON 指南 和 "How we built a new powerful JSON data type for ClickHouse"。
- 统一的值类型:ClickHouse 的