映射类型
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 位浮点数,但提供 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 对象作为单个字段存储,从而在无需完整映射的情况下,对嵌套键提供灵活、无模式的访问。在 ClickHouse 中,可以使用 String 类型实现类似的功能,但需要通过物化视图来完成相应的处理。 |
nested | Nested | 在用户将 flatten_nested 设为 0 的情况下,ClickHouse 的 Nested 列为分组子字段提供了类似的语义。 |
join | 不适用 | 没有直接的父子关系概念。在 ClickHouse 中这并不是必需的,因为支持跨表 JOIN 操作。 |
alias | Alias 列修饰符 | 可以通过字段修饰符来定义别名。可以对这些别名应用函数,例如 size String ALIAS formatReadableSize(size_bytes) |
range 类型(*_range) | Tuple(start, end) 或 Array(T) | ClickHouse 没有原生的区间类型,但数值区间和日期区间可以使用 Tuple(start, end) 或 Array 结构来表示。对于 IP 范围(ip_range),将 CIDR 值存储为 String,并使用诸如 isIPAddressInRange() 之类的函数进行判断。或者,可以考虑基于 ip_trie 的查找字典来实现高效过滤。 |
aggregate_metric_double | AggregateFunction(...) 和 SimpleAggregateFunction(...) | 使用聚合函数的状态和物化视图来建模预聚合的指标。所有聚合函数都支持聚合状态。 |
histogram | Tuple(Array(Float64), Array(UInt64)) | 使用数组或自定义模式手动表示桶及其计数。 |
annotated-text | String | 不提供对实体感知搜索或标注的内置支持。 |
completion, search_as_you_type | 不适用 | 没有内置自动补全或候选建议引擎。可以使用 String 和搜索函数来实现类似功能。 |
semantic_text | NA | 不支持原生语义搜索——需要生成向量嵌入并使用向量搜索。 |
token_count | Int32 | 在摄取过程中用于手动计算 token 数量,例如使用 length(tokens()) 函数,可配合物化列使用 |
dense_vector | Array(Float32) | 使用数组存储嵌入向量 |
sparse_vector | Map(UInt32, Float32) | 使用 Map 模拟稀疏向量。不支持原生稀疏向量。 |
rank_feature / rank_features | Float32, Array(Float32) | 不支持原生的查询时加权,但可以通过评分逻辑手动建模实现。 |
geo_point | Tuple(Float64, Float64) 或 Point | 使用由 (纬度,经度) 组成的元组。Point 是 ClickHouse 提供的一种数据类型。 |
geo_shape, shape | Ring, LineString, MultiLineString, Polygon, MultiPolygon | 原生支持地理空间形状和空间索引。 |
percolator | 不适用 | 没有为查询建立索引这种概念。请改用标准 SQL 和增量物化视图。 |
version | String | ClickHouse 没有原生的版本类型。请将版本存储为字符串,并在需要时使用自定义 UDF 执行语义比较。如果需要进行范围查询,建议将其规范化为数值格式。 |
备注
-
数组(Arrays):在 Elasticsearch 中,所有字段原生支持数组。在 ClickHouse 中,数组必须显式定义(例如
Array(String)),其优点是可以按特定位置访问和查询,例如an_array[1]。 -
多字段(Multi-fields):Elasticsearch 允许以多种方式索引同一字段(例如同时作为
text和keyword)。在 ClickHouse 中,必须通过单独的列或视图来实现这种模式。 -
Map 和 JSON 类型 - 在 ClickHouse 中,
Map类型通常用于建模如resourceAttributes和logAttributes这类动态键值结构。该类型通过允许在运行时添加任意键,实现灵活的无模式(schema-less)摄取,其理念与 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类型特别适合可观测性工作负载,在提供无模式摄取灵活性的同时,兼具原生 ClickHouse 类型的性能和可扩展性——这使其成为在动态属性字段中替代Map的理想选择。关于 JSON 类型的更多细节,推荐参考 JSON 指南 以及文章 "How we built a new powerful JSON data type for ClickHouse"。
- 统一的值类型:ClickHouse