Elasticsearch〜EC編
Elasticsearchをいざ使ってみようと思ってもなんのデータを扱っていいかわからない。
Webサーバのログとかでもいいのですが、ログは身近ではないので一つの物にたくさんの種類のデータが紐づくことが多いECの商品データを使ってみます。
ECでは、商品の検索・各カテゴリの商品の一覧・商品詳細をよく見ると思います。
商品数が多いECでは以下のようなことが多く発生いたします。
・商品が多く目的の商品・類似の商品にたどり着くためにユーザが検索を行う
・一つの商品にサイズ・カラーが複数関連し商品の表示出しわけが発生
・商品の画像登録・商品詳細文小さな変更が発生する
さらに購入データからユーザへお勧めの商品を提示したり、データ駆動型のシステムが多く目立ちます。
ElasticsearchのECのMappingを考えてみます。
商品ID
SKU(アイテム)
カテゴリ
金額
サイズ
カラー
在庫数
税金
送料
合計金額
表示ステータス
作成日
更新日
PUT ec_elasticsearch
{
"settings": {
"index": {
"analysis": {
"tokenizer": {
"kuromoji": {
"type": "kuromoji_tokenizer",
"mode": "search"
}
},
"analyzer": {
"japanese": {
"type": "custom",
"tokenizer": "kuromoji",
"filter": [
"pos_filter"
]
}
},
"filter": {
"pos_filter": {
"type": "kuromoji_part_of_speech",
"stoptags": [
"接続詞",
"助詞",
"助詞-格助詞",
"助詞-格助詞-一般",
"助詞-格助詞-引用",
"助詞-格助詞-連語",
"助詞-接続助詞",
"助詞-係助詞",
"助詞-副助詞",
"助詞-間投助詞",
"助詞-並立助詞",
"助詞-終助詞",
"助詞-副助詞/並立助詞/終助詞",
"助詞-連体化",
"助詞-副詞化",
"助詞-特殊",
"助動詞",
"記号",
"記号-一般",
"記号-読点",
"記号-句点",
"記号-空白",
"記号-括弧開",
"記号-括弧閉",
"その他-間投",
"フィラー",
"非言語音"
]
}
}
}
}
},
"mappings": {
"products_type": {
"properties": {
"product_id": {
"type": "string",
"index": "not_analyzed"
},
"product": {
"type": "nested",
"properties": {
"sku": {
"type": "string",
"index": "not_analyzed"
},
"category": {
"type": "string",
"index": "analyzed",
"analyzer": "japanese"
},
"price": {
"type": "double",
"index": "not_analyzed"
},
"size": {
"type": "string",
"index": "analyzed",
"analyzer": "japanese"
},
"color": {
"type": "string",
"index": "analyzed",
"analyzer": "japanese"
},
"quantity": {
"type": "double",
"index": "not_analyzed"
},
"tax": {
"type": "double",
"index": "not_analyzed"
},
"shipping": {
"type": "double",
"index": "not_analyzed"
},
"total": {
"type": "double",
"index": "not_analyzed"
},
"status": {
"type": "string",
"index": "not_analyzed"
},
"ec_create_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"ec_update_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
}
}
}
データを入れてみます
PUT _bulk
{"index":{"_id":"1","_index":"ec_elasticsearch","_type":"products_type"}}
{"product_id":"65536","product":[{"sku":"mbp-19760401","category":"apple_computer","price":"278800","size":"15inch","color":"space_gray","quantity":"10","tax":"22304","shipping":"756","total":"301860","status":"enable","ec_create_at":"2017-03-10 13:00:00","ec_update_at":"2017-03-10 13:00:00"}]}
{"index":{"_id":"2","_index":"ec_elasticsearch","_type":"products_type"}}{"product_id":"65536","product":[{"sku":"mbp-1976040102","category":"apple_computer","price":"278800","size":"15inch","color":"silver","quantity":"10","tax":"22304","shipping":"756","total":"301860","status":"enable","ec_create_at":"2017-03-10 13:00:00","ec_update_at":"2017-03-10 13:00:00"}]}
GET ec_elasticsearch/products_type/_search
{
"query": {
"nested": {
"path": "product",
"query": {
"term": { "product.sku": "mbp-19760401" }
}
}
}
}
検索結果
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "ec_elasticsearch",
"_type": "products_type",
"_id": "1",
"_score": 0.2876821,
"_source": {
"product_id": "65536",
"product": [
{
"sku": "mbp-19760401",
"category": "apple_computer",
"price": "278800",
"size": "15inch",
"color": "space_gray",
"quantity": "10",
"tax": "22304",
"shipping": "756",
"total": "301860",
"status": "enable",
"ec_create_at": "2017-03-10 13:00:00",
"ec_update_at": "2017-03-10 13:00:00"
}
]
}
}
]
}
}
上記の設定で色々な商品出たをもたせたクエリをする際下記の内容などが発生するかと思います
・公開済みの商品情報を対象に中カテゴリ別、メーカ別、価格別のナビゲーションを表示
・パンくずカテゴリ別売れ筋
公開済みフリーワードにマッチした商品情報を対象にカテゴリ別のトップ商品情報を表示
・各カテゴリの表示順は検索結果のスコアの高い商品情報を含むカテゴリを優先して表示
・フリーワード検索結果
公開済みかつフリーワードにマッチした商品情報をスコアの高い順で一覧表示
これらの情報を取得するために必要なクエリは"1回"ですみます。
最小限のクエリでここまでデータを自在に取得が可能になります。
規模の拡張が用意なElasticsearchでデータ管理とそのデータを可視化することができるKIBANAでよりデータの生かす方向が見えるのではないでしょうか?