1. データモデリングとは
データモデリングとは、データを整理し、組織化するためのプロセスです。具体的には、以下の3つの段階を経ます:
- 概念モデル → 逻辑モデル → データモデル(第三正規形)
データモデルは、使用するデータベースの種類に応じて設計されます。Elasticsearchの場合、検索や聚合操作の性能を考慮した設計が重要です。
2. Elasticsearchでのデータモデリング
Elasticsearchでのデータモデリングは以下の2つの観点から行います:
- データの保存、検索などの要件からエンティティの属性や関係を抽出し、論理モデルを形成します。
- 性能要件に基づいてインデックステンプレートやフィールドのマッピングを設計します。
Elasticsearchの基本単位はドキュメントです。ドキュメントは複数のフィールドから構成され、フィールドのモデリングがデータモデリングの中心となります。
2.1. フィールドのタイプのモデリング
(1) text vs keyword:
- text型: 全文検索に適しており、アナライザーによるトークナイズが行われます。
- keyword型: 非検索のテキスト(例: ID、メールアドレス)やフィルタリング、ソートに適しています。
(2) 構造化データ:
- 数値型: 必要な精度に合った型を選択します。
- enum型: keyword型として設定します。
- その他: 日付型、バイナリ型、ブーリアン型、地理情報型など。
2.2. 検索、集計、並び替えのモデリング
- 検索不要なフィールド: indexをfalseに設定します。
- 集計、並び替え不要なフィールド: doc_valuesをfalseに設定します。
- 更新頻度の高いkeyword型フィールド: eager_global_ordinalsをtrueに設定します。
2.3. 追加のデータ保存のモデリング
- フィールドの値を個別に保存する必要がある場合: storeをtrueに設定します。
- データ量の削減を図る場合: disable_sourceを使用します。
3. Elasticsearchデータモデリングの実例
3.1. 映射の動的作成
# 書籍情報のドキュメント作成
POST books/_doc
{
"タイトル": "Elasticsearch 7.2.0入門",
"著者": "Heal Chow",
"発行日": "2019-10-01",
"説明": "Elasticsearchの検索、インデックス、集計機能をマスターします。",
"カバーリンク": "https://healchow.com/images/29dMkliO2a1f.jpg"
}
# 映射の確認
GET books/_mapping
3.2. 映射の手動作成
# 映射を削除
DELETE books
# 映射を手動定義
PUT books
{
"mappings": {
"_source": { "enabled": true },
"properties": {
"タイトル": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 100
}
}
},
"著者": { "type": "keyword" },
"発行日": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyyMMddHHmmss||yyyy-MM-dd||epoch_millis"
},
"説明": { "type": "text" },
"カバーリンク": {
"type": "keyword",
"index": false
}
}
}
}
4. Elasticsearchデータモデリングのベストプラクティス
4.1. 関連性の処理方法
Elasticsearchは関連性の管理に適していません。以下の方法を使用します:
- オブジェクト型: 単層の関連性を表現します。
- ネスト型: 複数の関連性を表現します。
4.2. 过剰なフィールドの避ける
ドキュメント内のフィールド数が多いと以下の問題が発生します:
- メンテナンスが困難になります。
- クラスターステートのサイズが大きくなります。
解決策:
- dynamic設定をfalseにします。
- 必要に応じてフィールドの上限を設定します。
4.3. 正規表現検索の避ける
正規表現、プレフィックス、ワイルドカード検索は性能が悪いです。代わりに以下を使用します:
- フィルタリング
- 数値型や日付型などに分ける
4.4. 空値による集計の不正確さを避ける
空値のフィールドを回避するためにはnull_valueを設定します:
# null_valueを設定
PUT ratings
{
"mappings": {
"properties": {
"評価": {
"type": "float",
"null_value": 1.0
}
}
}
}