型のマッピング
Elasticsearch と ClickHouse は幅広いデータ型をサポートしますが、その基盤となるストレージおよびクエリモデルは本質的に異なります。このセクションでは、一般的に使用される Elasticsearch のフィールド型を、対応する ClickHouse の型がある場合にはその型へマッピングし、あわせて移行の指針となるコンテキストを提供します。等価な型が存在しない場合には、代替案や注意事項をコメントとして記載します。
| Elasticsearch タイプ | ClickHouse での同等機能 | コメント |
|---|---|---|
boolean | UInt8 または Bool | ClickHouse は、新しいバージョンでは UInt8 の別名として Boolean 型をサポートしています。 |
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 オブジェクト全体を単一フィールドとして格納し、完全なマッピングを定義することなく、ネストされたキーに柔軟かつスキーマレスにアクセスできるようにします。ClickHouse では、String 型を使用することで同様の機能を実現できますが、そのための処理はマテリアライズドビュー内で行う必要があります。 |
nested | Nested | ClickHouse の Nested カラムは、ユーザーが flatten_nested=0 を使用している場合、グループ化されたサブフィールドに対して同様のセマンティクス(動作)を提供します。 |
join | 該当なし | 親子関係という明示的な概念はありません。ClickHouse ではテーブル間の結合がサポートされているため、そのような概念は不要です。 |
alias | Alias 列修飾子 | エイリアスはフィールド修飾子として指定できます。これらのエイリアスには関数を適用できます。例: size String ALIAS formatReadableSize(size_bytes) |
range 型(*_range) | Tuple(start, end) または Array(T) | ClickHouse にはネイティブな range 型はありませんが、数値および日付の範囲は 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 | 該当なし | ネイティブなセマンティック検索機能はありません。埋め込みを生成してベクトル検索を利用してください。 |
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 | (緯度、経度)のタプルを使用します。Point は ClickHouse のデータ型として利用できます。 |
geo_shape, shape | Ring, LineString, MultiLineString, Polygon, MultiPolygon | 地理空間形状および空間インデックスをネイティブにサポート。 |
percolator | 該当なし | クエリにインデックスを張るという概念はありません。代わりに標準SQLとインクリメンタルマテリアライズドビューを使用してください。 |
version | String | ClickHouse にはネイティブな version 型はありません。バージョンは文字列として保存し、必要に応じてカスタム UDF 関数を使ってセマンティックな比較を行ってください。レンジクエリが必要な場合は、数値形式への正規化も検討してください。 |
補足事項
-
配列: Elasticsearch では、すべてのフィールドがネイティブに配列をサポートします。ClickHouse では、配列は明示的に定義する必要があります(例:
Array(String))。その代わり、特定の位置を参照してクエリできる利点があります(例:an_array[1])。 -
マルチフィールド: Elasticsearch では、同一フィールドを複数の方法でインデックス化できます(例:
textとkeywordの両方)。ClickHouse では、このパターンは別々のカラムまたはビューを使ってモデリングする必要があります。 -
Map 型と JSON 型 - ClickHouse では、
Map型がresourceAttributesやlogAttributesのような動的なキー・値構造を表現するためによく使われます。この型は、実行時に任意のキーを追加できるため、Elasticsearch の JSON オブジェクトと同様の発想で柔軟なスキーマレスなインジェストを可能にします。ただし、いくつか重要な制約があります:- 値の型は一様である必要がある: ClickHouse の
Mapカラムでは、値の型を一貫させる必要があります(例:Map(String, String))。変換なしに異なる型の値を混在させることはできません。 - パフォーマンスコスト:
Map内の任意のキーにアクセスするには、マップ全体をメモリに読み込む必要があり、パフォーマンス面で非効率になる場合があります。 - サブカラムがない: JSON と異なり、
Map内のキーは真のサブカラムとして表現されないため、ClickHouse がインデックス作成・圧縮・クエリを効率的に行う能力が制限されます。
これらの制約により、ClickStack は
Mapから、ClickHouse の拡張されたJSON型への移行を進めています。JSON型は、Mapの多くの欠点を解消します:-
真のカラム型ストレージ: 各 JSON パスはサブカラムとして保存されるため、効率的な圧縮、フィルタリング、およびベクトル化されたクエリ実行が可能です。
-
混在した型のサポート: 同じパス配下に異なるデータ型(例: 整数、文字列、配列)が、変換や型の統一なしに共存できます。
-
ファイルシステムのスケーラビリティ: 動的キー(
max_dynamic_paths)および型(max_dynamic_types)に対する内部制限により、高カーディナリティなキー集合であってもディスク上のカラムファイルが爆発的に増えることを防ぎます。 -
高密度なストレージ:
nullや欠損値はスパースに格納され、不要なオーバーヘッドを回避します。JSON型は、スキーマレスなインジェストの柔軟性とネイティブな ClickHouse 型の性能・スケーラビリティを兼ね備えており、特にオブザーバビリティ系ワークロードに適しています。そのため、動的な属性フィールドにおけるMapの理想的な代替となります。JSON 型の詳細については、JSON guide および "How we built a new powerful JSON data type for ClickHouse" を参照することをおすすめします。
- 値の型は一様である必要がある: ClickHouse の