跳转到主要内容
Elasticsearch 和 ClickHouse 都支持丰富的数据类型,但二者的底层存储和查询模型存在本质差异。本节将常用的 Elasticsearch 字段类型映射到对应的 ClickHouse 类型 (如果有) ,并提供相关背景信息以帮助指导迁移。对于没有对应类型的情况,我们也会在注释中提供替代方案或说明。
Elasticsearch 类型ClickHouse 对应项备注
booleanUInt8Bool在较新版本中,ClickHouse 支持将 Boolean 作为 UInt8 的别名。
keywordString用于精确匹配过滤、分组和排序。
textStringClickHouse 的全文搜索能力有限;标记化需要借助自定义逻辑,例如将 tokens 与数组函数结合使用。
longInt6464 位有符号整数。
integerInt3232 位有符号整数。
shortInt1616 位有符号整数。
byteInt88 位有符号整数。
unsigned_longUInt6464 位无符号整数。
doubleFloat6464 位浮点数。
floatFloat3232 位浮点数。
half_floatFloat32BFloat16最接近的对应类型。ClickHouse 没有 16 位浮点类型。ClickHouse 提供 BFloat16,但它不同于 IEEE-754 half-float:half-float 以较小的范围换取更高精度,而 bfloat16 则牺牲精度以获得更大的范围,因此更适合机器学习工作负载。
scaled_floatDecimal(x, y)用于存储定点数值。
dateDateTime对应秒级精度的日期类型。
date_nanosDateTime64ClickHouse 可通过 DateTime64(9) 支持纳秒级精度。
binaryString, FixedString(N)二进制字段需要进行 base64 解码。
ipIPv4, IPv6提供原生 IPv4IPv6 类型。
objectNested, Map, Tuple, JSONClickHouse 可使用 NestedJSON 对类似 JSON 对象的结构进行建模。
flattenedStringElasticsearch 中的 flattened 类型会将整个 JSON 对象存储为单个字段,从而无需完整映射即可灵活、无 schema 地访问嵌套键。在 ClickHouse 中,可使用 String 类型实现类似功能,但需要在 materialized view 中完成处理。
nestedNested在用户使用 flatten_nested=0 的前提下,ClickHouse 的 Nested 列可为成组子字段提供类似语义。
joinNA没有直接对应的父子关系概念。在 ClickHouse 中通常不需要,因为支持跨表 join。
aliasAlias 列修饰符可通过字段修饰符来支持别名。详见。例如,可对这些别名应用函数: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_doubleAggregateFunction(...)SimpleAggregateFunction(...)使用 aggregate function 状态和 materialized view 对预聚合指标进行建模。所有 aggregation 函数都支持 aggregate states。
histogramTuple(Array(Float64), Array(UInt64))可使用数组或自定义 schema 手动表示桶及其计数。
annotated-textString不内置支持实体感知搜索或注解。
completion, search_as_you_typeNA没有原生自动补全或建议器引擎。可通过 Stringsearch functions 实现类似效果。
semantic_textNA不支持原生语义搜索;请生成嵌入向量并使用向量搜索。
token_countInt32可在摄取期间手动计算标记数,例如使用 length(tokens()) 函数,或结合 Materialized 列实现。
dense_vectorArray(Float32)使用数组存储嵌入向量。
sparse_vectorMap(UInt32, Float32)可使用 Map 模拟稀疏向量。不支持原生稀疏向量。
rank_feature / rank_featuresFloat32, Array(Float32)不支持原生的查询时权重提升,但可以在评分逻辑中手动实现。
geo_pointTuple(Float64, Float64)Point使用 (纬度、经度) 的 Tuple。Point 也可作为 ClickHouse 类型使用。
geo_shape, shapeRing, LineString, MultiLineString, Polygon, MultiPolygon原生支持地理形状和空间索引。
percolatorNA没有“为查询建立索引”这一概念。请改用标准 SQL + 增量materialized views。
versionStringClickHouse 没有原生版本类型。请将版本存储为字符串,并在需要时使用自定义 UDF 函数进行语义化比较。如果需要范围查询,可考虑将其规范化为数值格式。

说明

  • 数组:在 Elasticsearch 中,所有字段都原生支持数组。在 ClickHouse 中,数组必须显式定义 (例如 Array(String)) ;其优势是可以访问和查询特定位置的元素,例如 an_array[1]
  • 多字段:Elasticsearch 允许以多种方式索引同一字段 (例如同时使用 textkeyword) 。在 ClickHouse 中,这种模式必须通过单独的列或视图来建模。
  • Map 和 JSON 类型 - 在 ClickHouse 中,Map 类型通常用于表示动态键值结构,例如 resourceAttributeslogAttributes。该类型允许在运行时添加任意键,从而实现灵活的无 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”
最后修改于 2026年6月10日