跳到主要内容
跳到主要内容

映射类型

Elasticsearch 和 ClickHouse 支持的数据显示类型非常丰富,但它们底层的存储与查询模型存在根本性差异。本节将常用的 Elasticsearch 字段类型映射到在 ClickHouse 中的对应类型(如有),并提供背景说明以帮助指导迁移。当不存在等价类型时,将在备注中给出替代方案或说明。

Elasticsearch 类型在 ClickHouse 中的对应类型注释
booleanUInt8Bool在较新版本的 ClickHouse 中,支持将 Boolean 作为 UInt8 的别名。
keywordString用于精确匹配的过滤、分组和排序。
textStringClickHouse 的全文检索功能有限;分词需要通过自定义逻辑实现,例如将 tokens 等函数与数组函数组合使用。
longInt6464 位有符号整数。
integerInt3232 位有符号整数。
shortInt1616 位有符号整数。
byteInt88 位有符号整数。
unsigned_longUInt64无符号 64 位整数。
doubleFloat6464 位浮点数。
floatFloat3232 位浮点数。
half_floatFloat32BFloat16最接近的等价类型。ClickHouse 不支持 16 位浮点数,但提供 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 对象作为单个字段存储,从而在无需完整映射的情况下,对嵌套键提供灵活、无模式的访问。在 ClickHouse 中,可以使用 String 类型实现类似的功能,但需要通过物化视图来完成相应的处理。
nestedNested在用户将 flatten_nested 设为 0 的情况下,ClickHouse 的 Nested 列为分组子字段提供了类似的语义。
join不适用没有直接的父子关系概念。在 ClickHouse 中这并不是必需的,因为支持跨表 JOIN 操作。
aliasAlias 列修饰符可以通过字段修饰符来定义别名。可以对这些别名应用函数,例如 size String ALIAS formatReadableSize(size_bytes)
range 类型(*_rangeTuple(start, end)Array(T)ClickHouse 没有原生的区间类型,但数值区间和日期区间可以使用 Tuple(start, end)Array 结构来表示。对于 IP 范围(ip_range),将 CIDR 值存储为 String,并使用诸如 isIPAddressInRange() 之类的函数进行判断。或者,可以考虑基于 ip_trie 的查找字典来实现高效过滤。
aggregate_metric_doubleAggregateFunction(...)SimpleAggregateFunction(...)使用聚合函数的状态和物化视图来建模预聚合的指标。所有聚合函数都支持聚合状态。
histogramTuple(Array(Float64), Array(UInt64))使用数组或自定义模式手动表示桶及其计数。
annotated-textString不提供对实体感知搜索或标注的内置支持。
completion, search_as_you_type不适用没有内置自动补全或候选建议引擎。可以使用 String搜索函数来实现类似功能。
semantic_textNA不支持原生语义搜索——需要生成向量嵌入并使用向量搜索。
token_countInt32在摄取过程中用于手动计算 token 数量,例如使用 length(tokens()) 函数,可配合物化列使用
dense_vectorArray(Float32)使用数组存储嵌入向量
sparse_vectorMap(UInt32, Float32)使用 Map 模拟稀疏向量。不支持原生稀疏向量。
rank_feature / rank_featuresFloat32, Array(Float32)不支持原生的查询时加权,但可以通过评分逻辑手动建模实现。
geo_pointTuple(Float64, Float64)Point使用由 (纬度,经度) 组成的元组。Point 是 ClickHouse 提供的一种数据类型。
geo_shape, shapeRing, LineString, MultiLineString, Polygon, MultiPolygon原生支持地理空间形状和空间索引。
percolator不适用没有为查询建立索引这种概念。请改用标准 SQL 和增量物化视图。
versionStringClickHouse 没有原生的版本类型。请将版本存储为字符串,并在需要时使用自定义 UDF 执行语义比较。如果需要进行范围查询,建议将其规范化为数值格式。

备注

  • 数组(Arrays):在 Elasticsearch 中,所有字段原生支持数组。在 ClickHouse 中,数组必须显式定义(例如 Array(String)),其优点是可以按特定位置访问和查询,例如 an_array[1]

  • 多字段(Multi-fields):Elasticsearch 允许以多种方式索引同一字段(例如同时作为 textkeyword)。在 ClickHouse 中,必须通过单独的列或视图来实现这种模式。

  • Map 和 JSON 类型 - 在 ClickHouse 中,Map 类型通常用于建模如 resourceAttributeslogAttributes 这类动态键值结构。该类型通过允许在运行时添加任意键,实现灵活的无模式(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"