$30 off During Our Annual Pro Sale. View Details »

ElasticsearchでECサイトにおける高速検索/集計を実現する

樋口慎
October 14, 2022

 ElasticsearchでECサイトにおける高速検索/集計を実現する

Elastic Community Conference 2022 の発表資料です。
https://community-conference.elastic.co/session/309670

セッション概要
===========================================
ECサイト検索における性能改善についてのセッションです。

ECサイトは商品の属性(色や重量、内容量など)によって、件数を集計して表示したり、チェックボックスによってフィルタリングをおこなったりする機能を有するものが一般的です。

Elasticsearchでそういった集計・フィルタリングを実現するための商品データを扱うために各商品の属性を個別のフィールドとして扱うと、属性値のバリエーション数が膨大になります。 これは、商品の種類によって保持している属性値の種類が異なるためです。

フィールド数が膨大になるとヒープ利用効率が悪くなるため、ヒープが逼迫しクエリ時にGCが発生しやすくなる場合があります。これによって検索性能が出なくなります。 また、ドキュメント登録時には頻繁に mapping が更新されるため、インデクシングのパフォーマンスを低下させる恐れもあります。

上記の課題を解決し、高速な検索・集計をElasticsearchで実現する方法やTipsについてお話します。

樋口慎

October 14, 2022
Tweet

More Decks by 樋口慎

Other Decks in Technology

Transcript

  1. ECサイトにおいて
    高速検索/集計を実現する
    2022/02/12
    アクロクエストテクノロジー株式会社
    Elastic Certified Professional
    樋口慎

    View Slide

  2. 自己紹介
    ● アクロクエストテクノロジー株式会社
    ● 樋口 慎(@shin0higuchi)
    ● 業務:Elasticコンサルティング全般、データ分析、システム開発
    ● その他
    ○ Elastic Certified Professional
    (世界初 Elastic Certification 3種取得)
    ○ Elasticsearch NEXT STEP 執筆
    ○ Elastic User Group Tokyo 運営

    View Slide

  3. アクロクエストテクノロジー株式会社
    ● オープンな社風が特徴のITベンチャー
    ○ 働きがいのある会社ランキング日本1位(3回受賞)
    ○ 『日本でいちばん大切にしたい会社』大賞 審査委員会特別賞
    ○ 組織コンサルティング事業を展開
    ● データ活用ビジネス
    ○ Elastic Stack活用コンサルティング
    ✓ 設計/構築/性能改善/運用支援など
    ✓ Elastic認定資格者:8名
    ○ IoTデータ分析プラットフォーム
    ○ 機械学習/AI

    View Slide

  4. 目次
    ECサイトにおける課題/Elasticsearchでのアプローチ
    3
    さいごに
    4
    ECサイト検索の機能要件
    2
    Elasticsearchのユースケース
    1

    View Slide

  5. Elasticsearchのユースケース

    View Slide

  6. 全文検索基盤「Elastic Stack」
    データ収集/全文検索/運用管理をワンストップで実現
    Kibana
    Elasticsearch
    Beats
    •様々なデータソースからデータ収集
    •RDBからのデータ取得も可能
    •全文検索/リアルタイム分析エンジン
    •大量データに対する高速集計/検索
    •ビッグデータ対応可視化/分析ツール
    •各種運用管理機能
    Logstash

    View Slide

  7. Search
    Observability
    Elasticsearchの代表的なユースケース
    Security
    高速検索、スキーマレス、多彩な検索に対応
    様々な構造化/非構造化データを取り込み検索する。
    ログ、メトリクス、APM、Uptime、UX
    システムのあらゆる情報を収集し、状態を把握する。
    SIEM、エンドポイント保護、クラウドセキュリティ
    セキュリティ機器などのログを集約し、可視化・異常検知を行う。

    View Slide

  8. 企業内検索
    Webサイト検索
    アプリケーション検索 Webアプリケーションの検索機能をElasticsearchにより実現。
    記事検索、ECサイト、レストラン検索、フリマアプリなど。
    クローリングによりWebサイトの情報を収集し、横断的に検索。
    Googleのような「Web検索エンジン」機能を提供する。
    Elasticsearchの検索ユースケース例
    企業内や各種クラウドストレージに蓄積されたファイル内容を検索。
    各種クラウドサービス内のメッセージを横断的に検索。

    View Slide

  9. ECサイト検索の機能要件

    View Slide

  10. ECサイト検索の機能要件
    • 一般的にECサイト検索に求められる機能要件
    親子関係を
    含む
    データ構造
    ファセット
    集計
    レコメンド/
    サジェスト
    フィルタリング
    商品検索
    商品グループ
    SKU ※1
    価格
    レビュー数
    商品属性
    全文検索
    表記ゆれ対応
    類義語対応
    商品属性絞込み
    範囲検索
    もしかして検索
    クエリ補完
    パーソナライズ
    ※1:Stock Keeping Unit ⇒ 管理・販売の最小単位

    View Slide

  11. ECサイト検索の機能要件
    • 一般的にECサイト検索に求められる機能要件
    親子関係を
    含む
    データ構造
    ファセット
    集計
    レコメンド/
    サジェスト
    フィルタリング
    商品検索
    商品グループ
    SKU ※1
    価格
    レビュー数
    商品属性
    全文検索
    表記ゆれ対応
    類義語対応
    商品属性絞込み
    範囲検索
    もしかして検索
    クエリ補完
    パーソナライズ
    ※1:Stock Keeping Unit ⇒ 管理・販売の最小単位

    View Slide

  12. ECサイト検索の機能要件と画面イメージ
    軍手
    軍手A 白
    \1,000
    レビュー
    □ 4以上
    ☑ 3以上
    □ 2以上
    □ 1以上
    軍手B 厚手
    \1,500
    手袋 丈夫 ゴム製
    \2,000
    ブランド
    □ XX (100)
    □ YY (57)
    □ ZZ (12)



    40件の商品があります
    商品検索
    フィルタリング
    データの親子関係
    検索結果画面に何を表示するかは、サイトによって異なる。
    例)結果画面には商品Gのみ、詳細画面でSKU一覧を表示
    例)結果画面にSKUを一覧表示
    ファセット集計

    View Slide

  13. ECサイト検索の特徴
    ● データ特性
    ○ 検索対象となる商品グループ/SKUの数が多い。
    商品グループで1000万、SKU単位で2000万を超える事例もある。
    ○ 商品属性の種類が多い。 (例:色、サイズ、etc.)
    扱う商品が多様な場合、数万以上となる。
    ● 性能要件
    ○ 単発クエリの検索性能要件(100ms以下~1000ms以下)
    クエリ内のファセット集計の数が多い。集計性能のチューニングも重要。
    ○ 同時検索数の性能要件も存在する。(同時10人~500人)

    View Slide

  14. ECサイト検索でElasticsearchを利用する際の課題
    ● マッピング爆発(性能低下)
    ○ 商品属性の数(フィールド数)が膨大になるためヒープ使用量が増大する。
    ○ ヒープが逼迫することで検索性能/クラスタ安定性に悪影響が出る。
    ● データ設計に工夫が必要
    ○ 検索要件によってデータ設計が大きく変わる
    検索要件の例:商品Gの件数を集計する、SKU単位のクロスヒット回避など

    View Slide

  15. EC検索の課題①
    • 商品ごとに固有の属性があるため
    商品属性のユニーク数が非常に多い。
    • 1商品属性1フィールドとして設計すると
    フィールド数が膨大(多いと数万件)になる。
    • フィールド数の増加に伴い、ヒープ使用量が増大する。
    • 検索時に使用可能なメモリが不足するため、
    検索性能/クラスタ安定性/同時検索可能数も低下。
    マッピング爆発

    View Slide

  16. Flattened Field Type によるアプローチ
    ● Elasticsearch7.3から導入されたFlattened field typeを利用することで、
    フィールド数の増大を解決することができる。
    参考)https://www.elastic.co/guide/en/elasticsearch/reference/current/flattened.html
    ● Flattened field type
    ○ オブジェクトの子フィールドを、まとめて1つのフィールドとして扱うデータ型
    ○ 子フィールドのユニーク数が膨大 or 数が不明な場合に有用
    {
    "object": {
    "xxx": "aaa",
    "yyy": "bbb",
    "zzz": "ccc"
    }
    }
    オブジェクトの例 ①Flattenedを利用しない場合、
    ・object.xxx
    ・object.yyy
    ・object.zzz
    の3フィールドが作られる。
    ②Flattenedを利用する場合、
    object という1フィールドのみが作られる。

    View Slide

  17. Flattened Field Type の特徴
    ● 以下のようにオブジェクトを単一のフィールドとして扱えるため、
    フィールド数を大きく減らすことが可能
    ● クエリ時には "attributes.length" のような記述で子階層にアクセス可能
    {
    "length": "200mm",
    "color": "青",
    "weight": "500g",
    "width" : "10mm",
    ・・・
    }
    {
    "attributes": {
    "length": "200m",
    "color": "青",
    "weight": "500g",
    "width" : "10mm",
    ・・・
    }
    }
    Flattened 未使用 Flattened 使用
    ・属性の数だけフィールドが必要
    ・数万フィールドにおよぶ場合も
    "attributes" という単一のフィールド
    として扱うことが可能

    View Slide

  18. 実際の利用例
    ● 商品属性名の重複を考慮し、flattened配下のフィールド名は
    名称ではなくID化する。
    {
    "attributes": {
    "00001": "200mm",
    "00002": "青",
    "00003": "500g",
    "00004" : "10mm",
    ・・・
    }
    }
    属性IDと属性名称の対応は、
    別フィールドや、Elasticsearch外部に持たせることが多い
    (Elasticsearchには検索に必要な情報のみ保持)
    00001 → 長さ: 200mm
    00002 → 色 : 青
    00003 → 重さ:500g
    00004 → 太さ:10mm

    View Slide

  19. ● Terms Aggsで集計
    集計時のクエリ例
    "aggs": {
    "attributes_00001":{
    "terms": {
    "field": "attributes.00001"
    }
    },
    "attributes_00002":{
    "terms": {
    "field": "attributes.00002"
    }
    }
    }
    軍手
    軍手A 白
    \1,000
    長さ
    □ 200mm (30)
    □ 100mm (50)
    □ 80mm (25)
    □ 50mm (120)
    軍手B 厚手
    \1,500
    手袋 丈夫 ゴム製
    \2,000

    □ 白 (100)
    □ 黒 (57)
    □ 灰 (12)



    40件の商品があります
    00002 → 色
    00001 → 長さ

    View Slide

  20. EC検索の課題② • ECサイトによって、検索結果の表示/件数、ファセット集
    計などの対象を商品グループ、SKUのどちらにするかの
    要件が異なる。
    • 要件が商品グループ主体なのかSKU主体なのかによって
    最適なデータ構造が大きく異なるため、要件を明確にする
    こと、要件に応じて最適なデータ設計を行うことが重要に
    なる
    データ設計に工夫が必要

    View Slide

  21. 基本的なデータ構造
    商品グループA
    SKU1
    SKU2
    SKU3
    商品グループB
    商品名
    カテゴリ
    ブランド
    商品概要
    商品属性
    価格

    色:白、サイズ:A4、価格:\300
    色:青、サイズ:B5、価格:\240
    長さ:120mm、入数:10、価格:\500

    View Slide

  22. 基本的なデータ構造(RDBの場合)
    商品GID 商品G名 カテゴリ …
    00001 商品A 日用品
    00002 商品B 日用品
    00003 商品C 工具
    SKU ID 商品GID(FK) 価格 サイズ 長さ
    00001 00001 300 A4 -
    00002 00001 240 B5 -
    00003 00002 500 - 100mm
    商品グループテーブル SKUテーブル
    検索時には、
    2つのテーブルをJOINする

    View Slide

  23. 基本的なデータ構造(Elasticsearchの場合)
    ● Elasticsearchでは、複数テーブル(インデックス)のJOINはサポートされていない
    ● JOINに相当するデータ設計として以下の3パターンがある。
    No. データ構造 ドキュメント単位 親子関係の表現方法
    1 SKUに非正規化 SKU 全ドキュメントが、
    商品グループ(親)の情報を持つ
    2 Nested Field Type 商品グループ 配列でSKUのオブジェクトを持つ
    (Nested型)
    3 Parent Child 商品グループ / SKU Join Field Typeで親子関係を表現

    View Slide

  24. No.1: SKUに非正規化
    ドキュメント単位:SKU
    {"product_group_id": "00001", "product_name": "商品A", "sku_id": "00001", "price": 300, "color": "白", "サイズ": "A4"}
    {"product_group_id": "00001", "product_name": "商品A", "sku_id": "00002", "price": 240, "color": "黒", "サイズ": "B5"}
    商品GID 商品G名 カテゴリ
    00001 商品A 日用品
    SKU ID 価格 色 サイズ
    00002 240 黒 B5
    SKU ID 価格 色 サイズ
    00001 300 白 A4
    商品グループ SKU
    商品グループ情報は各ドキュメントに重複して記載

    View Slide

  25. No.1: SKUに非正規化
    ドキュメント単位:SKU
    {"product_group_id": "00001", "product_name": "商品A", "sku_id": "00001", "price": 300, "color": "白", "サイズ": "A4"}
    {"product_group_id": "00001", "product_name": "商品A", "sku_id": "00002", "price": 300, "color": "黒", "サイズ": "B5"}

    ● メリット
    ○ クエリがシンプルに記述でき、検索が高速である
    ○ SKU同士のクロスヒットを回避できる
    ● デメリット
    ○ 商品グループの集計が近似計算(不正確)になってしまう
    ○ 商品グループの更新をする場合、紐づく全てのSKU更新が必要。(更新が遅い)

    View Slide

  26. No.2: Nested Field Type
    ドキュメント単位:商品グループ
    商品GID 商品G名 カテゴリ
    00001 商品A 日用品
    SKU ID 価格 色 サイズ
    00002 240 黒 B5
    SKU ID 価格 色 サイズ
    00001 300 白 A4
    商品グループ SKU
    {
    "product_group_id": "00001",
    "product_name": "商品A",
    "sku": [
    {"sku_id": "00001", "price": 300, "color": "白", "サイズ": "A4"},
    {"sku_id": "00002", "price": 300, "color": "黒", "サイズ": "B5"},

    ]
    }

    View Slide

  27. No.2: Nested Field Type
    ドキュメント単位:商品グループ
    {
    "product_group_id": "00001",
    "product_name": "商品A",
    "sku": [
    {"sku_id": "00001", "price": 300, "color": "白", "サイズ": "A4"},
    {"sku_id": "00002", "price": 300, "color": "黒", "サイズ": "B5"},

    ]
    } skuフィールドのデータ型を "nested" にする
    ● メリット
    ○ SKU同士のクロスヒットを回避できる
    ○ 商品グループの集計が正確
    ● デメリット
    ○ クエリが複雑になる/非正規化アプローチと比較して検索速度が遅い
    ○ SKUを更新時、更新対象SKU以外のフィールドの再登録が必要。(更新が遅い)

    View Slide

  28. No.3: Parent-Child
    ドキュメント単位:商品グループ/SKU
    商品GID 商品G名 カテゴリ
    00001 商品A 日用品
    SKU ID 価格 色 サイズ
    00002 240 黒 B5
    SKU ID 価格 色 サイズ
    00001 300 白 A4
    商品グループ SKU
    { "id": "product_00001", "product_name": "商品A", "relation": "product_group"}

    {"id": "sku_00001", "price": 300, "color": "白", "サイズ": "A4", "relation": {"name":"sku", "parent": "product_00001"}}
    {"id": "sku_00002", "price": 300, "color": "黒", "サイズ": "B5", "relation": {"name":"sku", "parent": "product_00001"}}

    View Slide

  29. No.3: Parent-Child
    ドキュメント単位:商品グループ/SKU
    { "id": "product_00001", "product_name": "商品A", "relation": "product_group"}

    {"id": "sku_00001", "price": 300, "color": "白", "サイズ": "A4", "relation": {"name":"sku", "parent": "product_00001"}}
    {"id": "sku_00002", "price": 300, "color": "黒", "サイズ": "B5", "relation": {"name":"sku", "parent": "product_00001"}}

    relationフィールドをjoin型にして、ドキュメント種別(商品 or SKU)や親のIDを保持する
    ● メリット
    ○ SKU同士のクロスヒットを回避できる
    ○ 商品グループの集計が正確
    ○ SKU単体でのデータ更新が可能。(Nestedより更新が高速)
    ● デメリット
    ○ クエリが複雑になる
    ○ Nestedよりさらに検索速度が遅い

    View Slide

  30. Elasticsearchでのデータ構造まとめ
    各データ構造に適した検索要件/特徴
    No. データ構造
    適した
    検索要件
    クエリ/
    検索速度
    クロスヒット
    回避
    商品グループの
    集計
    データ更新
    1 SKUに非正規化 SKU主体 シンプル/高速 可能 近似 遅い
    2 Nested Field Type 商品グループ主体 複雑/遅い 可能 正確 遅い
    3 Parent Child 商品グループ主体 複雑/とても遅い 可能 正確 速い
    ● SKU主体の要件の場合、「SKUに非正規化」を採用する。
    ただし、商品グループの集計が必須要件の場合は不向きである。
    ● 商品グループ主体の要件の場合、NestedまたはParent Childを採用する。
    ● データ更新の頻度/量が
    少ない場合→検索がParent Childより高速なNestedを採用する
    多い場合→検索は遅いがデータ更新が高速なParent Childを採用する

    View Slide

  31. まとめ
    ● ElasticsearchをECサイト検索で利用する場合、以下のアプローチが重要である。
    ○ 商品属性フィールドのマッピング爆発を回避するために「Flattened型」を利用する。
    ○ 検索要件に応じて適切なデータ設計を行う必要がある。
    ᐨ SKU主体の要件の場合、「SKUに非正規化」を採用する。
    ただし、商品グループの集計が必須要件の場合は不向きである。
    ᐨ 商品グループ主体の要件の場合、NestedまたはParent Childを採用する。
    ᐨ データ更新の頻度/量が
    少ない場合→検索がParent Childより高速なNestedを採用する
    多い場合→検索は遅いがデータ更新が高速なParent Childを採用する

    View Slide

  32. アクロクエストテクノロジーでは
    データ分析/機械学習 に取り組みたい
    エンジニアを募集しています
    興味を持たれた方は
    @shin0higuchi までご連絡ください。

    View Slide

  33. ご清聴ありがとうございました
    2022/02/12
    アクロクエストテクノロジー株式会社
    Elastic Certified Professional
    樋口慎

    View Slide