はじめに
VAIS:Cのインタラクティブ チュートリアルをやったのでメモ書きを残します。
あくまで個人用で書いているので最低限の説明とリンクまとめになります。
間違いなどありましたらご指摘いただけると幸いです。
セッティング
環境設定
カタログデータインポート
user_import_data_to_catalog.sh
商品カタログ
商品カタログのimport
BigQueryからimport
Products.importAPIを使う。
チュートリアルのサンプルコード
import_products_big_query_table
ざっくりいうとBig Queryへの接続・認証情報を含むリクエストオブジェクトを作成し、importAPIをコールするだけ。
Cloud Storageからimport
チュートリアルのサンプルコード
import_products_gcs.py
前提:Cloud StorageにJson形式で商品が入っていること。
アップロード方法はこちら
商品Jsonサンプル
{"id": "GGCOGOAC101259","name": "GGCOGOAC101259","title": "#IamRemarkable Pen","brands": ["#IamRemarkable"],"categories": ["Office"],"priceInfo": {"cost": "12.0","currencyCode": "USD","originalPrice": "45.0","priceEffectiveTime": "2020-08-01T12:00:00+00:00","priceExpireTime": "2120-08-01T12:00:00+00:00","price": "16"},"colorInfo": {"colorFamilies": ["Blue"],"colors": ["Light blue","Blue","Dark blue"]},"availability": "IN_STOCK","availableQuantity": 50,"availableTime": "2021-10-11T12:00:00+00:00","images": [{"height": "300","width": "400","uri": "https://shop.googlemerchandisestore.com/store/20160512512/assets/items/images/GGCOGOAC101259.jpg"}],"retrievableFields": "name,title,brands,categories,priceInfo,colorInfo,availability,images,attributes.material,attributes.ecofriendly,attributes.style,attributes.collection,uri","attributes":[ {"key":"material", "value": {"indexable": "true","searchable": "true","text": ["Metal","Recycled Plastic"]}}],"uri": "https://shop.googlemerchandisestore.com/Google+Redesign/Office/IamRemarkable+Pen"}
{"id": "GGOEAAEC172013","name": "GGOEAAEC172013","title": "Android Embroidered Crewneck Sweater","brands": ["Android"],"categories": ["Apparel"],"priceInfo": {"cost": "12.0","currencyCode": "USD","originalPrice": "45.0","priceEffectiveTime": "2020-08-01T12:00:00+00:00","priceExpireTime": "2120-08-01T12:00:00+00:00","price": "35"},"availability": "OUT_OF_STOCK","images": [{"height": "300","width": "400","uri": "https://shop.googlemerchandisestore.com/store/20160512512/assets/items/images/noimage.jpg"}],"sizes": ["XS","S","M","L","XL"],"retrievableFields": "name,title,brands,categories,priceInfo,colorInfo,availability,images,attributes.material,attributes.ecofriendly,attributes.style,attributes.collection,uri","attributes":[ {"key":"ecofriendly", "value": {"indexable": "false","searchable": "false","text": ["Low-impact fabrics","recycled fabrics","recycled packaging","plastic-free packaging","ethically made"]}}],"uri": "https://shop.googlemerchandisestore.com/Google+Redesign/Apparel/Android+Embroidered+Crewneck+Sweater"}
{"id": "GGPRAHPL107110","name": "GGPRAHPL107110","title": "Android Iconic Hat Green","brands": ["Android"],"categories": ["Apparel"],"priceInfo": {"cost": "12.0","currencyCode": "USD","originalPrice": "45.0","priceEffectiveTime": "2020-08-01T12:00:00+00:00","priceExpireTime": "2120-08-01T12:00:00+00:00","price": "16"},"colorInfo": {"colorFamilies": ["Green"],"colors": ["Olive","Grass green","Light green"]},"availability": "IN_STOCK","availableQuantity": 50,"availableTime": "2021-10-11T12:00:00+00:00","images": [{"height": "300","width": "400","uri": "https://shop.googlemerchandisestore.com/store/20160512512/assets/items/images/GGOEAHPL130910.jpg"}],"retrievableFields": "name,title,brands,categories,priceInfo,colorInfo,availability,images,attributes.material,attributes.ecofriendly,attributes.style,attributes.collection,uri","uri": "https://shop.googlemerchandisestore.com/Google+Prize+Portal/Android+Iconic+Hat+Green"}
こちらもGCSバケットへの接続・認証情報を設定したリクエストオブジェクトを作って、それを引数にProducts.importAPIを呼ぶだけ。
インラインでimport
商品データをコード内に埋め込んで(インラインで)インポートする方法。
チュートリアルのサンプルコード
import_products_inline_source.py
Product()という商品情報クラスがある。
Productクラスにはtitle, id, categoriesなどのフィールドがある。
各フィールドに値をセットする。
PriceInfoクラスやColorInfoクラスなどクラスが用意されている場合はそれを使う。
そうして作ったProductオブジェクトをリクエストオブジェクトにセットしてProducts.importAPIを呼ぶ。
詳細はこちら
商品オブジェクトCRUD
- CreateProductRequest
- GetProductRequest
- UpdateProducctRequest
- DeleteProductRequest
この4つのAPIを使う。
PythonのProductServiceClientクラスで用意されているメソッドからgRPCエンドポイントでGoogle Cloud Retail APIにアクセスしてる。
HTTP / JSON も対応してる。
Cloud Endpoints はプロトコルのコード変換をサポートしており、クライアントは HTTP / JSON を使用して gRPC API にアクセスできます。HTTP / JSON から gRPC へのコード変換は Extensible Service Proxy(ESP)が行います。
https://cloud.google.com/endpoints/docs/grpc/transcoding?utm_source=chatgpt.com&hl=ja
らしい。
なのでHTTP / JSON でもOK。
CreateProductRequest
商品(Product)の詳細はこちら。
チュートリアルのサンプルコード
crud_product.py
サンプルコードのgenerrate_producctのように作成したいProductオブジェクトを生成する。
product(作成する商品オブジェクト), product_id(プロダクトID), parent(カタログブランチ名)は必須。
Retail APIリファレンス
Python ProductServiceClient
GetProductRequest
nameフィールドを指定してget_product APIを呼ぶ。
crud_product.py
Retail APIリファレンス
Python ProductServiceClient
UpdateProducctRequest
更新したProductを作成し、update_product APIを呼ぶ。
crud_product.py
Retail APIリファレンス
Python ProductServiceClient
DeleteProductRequest
nameフィールドを指定してdelete_product APIを呼ぶ。
crud_product.py
Retail APIリファレンス
Python ProductServiceClient
商品作成
少量の商品作成なら上記のCreateProductRequest
大量の作成ならimport_productsを使う。
商品には3つのタイプがある。
PRIMARY - 関連商品ファミリーの主要商品。Retail の観点からは、インデックス登録、検索提供、予測のためのメインユニットでもあります。複数の VARIANT 商品を親商品としてグループ化できます。
VARIANT - SKU(在庫管理単位)。通常は、親 PRIMARY 商品と共通の属性を共有するだけでなく、色やサイズ、価格などのバリエーション属性を持つ商品アイテム。
COLLECTION - ネックレス付きの宝石、イヤリング、指輪など、PRIMARY や VARIANT の商品がまとめて販売される商品アイテム。
CreateProductRequestを引数にgenerate_product()メソッドを使用して商品を作成する。
create_product.py
商品取得
GetProductRequestを引数にget_product()を取得する。
GetProductRequestにはnameフィールドに商品リソースを指定する。
projects//locations/global/catalogs//branches//products/
商品更新
productとallow-missingを指定したUpdateProductRequestを使ってupdate_productを呼び出す。
update_product.py
商品削除
nameフィールドを指定したDeleteProductRequestを生成し、delete_productを呼び出す。
delete_product
ユーザーイベント
イベントインポート
Google Cloud Storageからのインポート
こんな感じのユーザーイベントデータを用意する。
{"eventType":"home-page-view","visitorId":"bjbs_group1_visitor1","eventTime":"2025-07-26T10:27:42+00:00"}
{"eventType":"search","visitorId":"bjbs_group1_visitor1","eventTime":"2025-07-26T10:27:42+00:00","searchQuery":"RockerJeans teenagers blue jeans"}
{"eventType":"search","visitorId":"bjbs_group1_visitor1","eventTime":"2025-07-26T10:27:42+00:00","searchQuery":"SocksUnlimited teenagers black socks"}
{"eventType":"detail-page-view","visitorId":"bjbs_group1_visitor1","eventTime":"2025-07-26T10:27:42+00:00","productDetails":{"product":{"id":"GGCOGAEC100616"},"quantity":3}}
create_bucketとupload_blobでGCSにバケットを作成し、イベントデータをアップロードする。
events_create_gcs_bucket.py
環境変数にバケット名を登録する。
export EVENTS_BUCKET_NAME=hogehoge
import_user_events_gcs.pyを参考にユーザーイベントをGCSからRetailカタログにインポートする。
BigQueryからのインポート
GCSの時と同様にイベントデータを作成。
- データセット作成。
- ユーザーイベント用スキーマにテーブルを作成。
- 作成したイベントデータをアップロード。
1~3の手順はcreate_bq_dataset、create_bq_table、upload_data_to_bq_tableを使用する。
参考:events_create_bigquery_table.py
次にBigQuery テーブルから Retail カタログにユーザー イベントをインポートする。
参考:import_user_events_big_query.py
Retail API は内部的に指定されたBQテーブルのデータを、一時的なGCS バケットにエクスポートし、そこからRetailのデータベースにインポートしてるらしい。
インラインでのインポート
import_user_events_inline.pyを参考にコード内で作成したイベントをRetailに登録する。
ユーザーイベント作成
WriteUserEventRequestインスタンスを作成する。
WriteUserEventRequestにはparent, user_eventの2つの必須フィールドがある。
parent - 親カタログ名。
projects//locations/global/catalogs/default_catalog
user_event - ユーザーイベント
event_type: "home-page-view"
visitor_id: "test_visitor_id"
event_time {
seconds: 1753620119
}
参考:
検索
基本の検索
-
placement - リソース名
default_search_placement = ( "projects/" + project_id + "/locations/global/catalogs/default_catalog/placements/default_search" )
-
VisitorId - 訪問者の一意の識別子
-
query - 検索したい単語
SearchRequestクラスに上記3つを設定する。SearchRequestクラスを引数にSearchServiceClient().searchを呼び出す。
system attrivutesやcustom attributesでも検索できる。
参考:
search_simple_query.py
SearchServiceClient
SearchRequest
ページわけ
SearchRequest.page_sizeにページサイズを設定する。
SearchRequestクラスを引数にSearchServiceClient().searchを呼び出す。
レスポンスにnext_page_tokenが含まれて返ってくるので、
SearchRequest.page_tokenにnext_page_tokenを指定すると次のページを取得できる。
参考:search_with_pagination.py
クエリ拡張
SearchRequest().QueryExpansionSpec()にSearchRequest.QueryExpansionSpec.Condition.AUTOを設定する。
SearchRequestクラスを引数にSearchServiceClient().searchを呼び出す。
参考:search_with_query_expansion_spec.py
QueryExpansionSpec.condition
フィルタ
search_request.filterに下記のようなフィルタ式を設定する。
(colorFamilies: ANY("Black"))'
ANY 関数は、フィールドにリテラルが含まれるかどうかを判定。
サポートされているフィルタフィールドはこちら
右辺のANYの部分はANY関数以外にも
- IN関数
IN(15.0, 45.0)
- 比較演算子
filter_ = 'price >= 15.0 AND price < 45.0'
- AND, OR演算子
filter_ = expression { " AND " | " OR " } expression
を使える。
SearchRequestクラスを引数にSearchServiceClient().searchを呼び出す。
並び替え
search_request.order_byに下記のように並べ替え式を設定する。
単一フィールド並び替え
order = 'price desc'
複数フィールド並び替え
order = 'price desc, discount'
order = 'brands, attributes.collection desc'
サポートされている並び替えフィールドはこちら
SearchRequestクラスを引数にSearchServiceClient().searchを呼び出す。
ブースト
ブーストって何?
https://cloud.google.com/retail/docs/serving-control-rules?hl=ja#boost-bury
上述のフィルタ式に対してブースト値を設定することで商品順序を上げたり下げたりできる。
ざっくりいうとフィルタ式で指定した特定の商品群の表示順をコントロールできる。
SearchRequest.BoostSpec.ConditionBoostSpec()のcondisionにフィルタ式を設定する。
SearchRequest.BoostSpec.ConditionBoostSpec()のboostにブースト値を-1~1で設定する。
condition_boost_spec = SearchRequest.BoostSpec.ConditionBoostSpec()
condition_boost_spec.condition = '(colorFamilies: ANY("Blue"))'
condition_boost_spec.boost = 0.5
リダイレクト制御
placementに変数を適用する。
default_search_placement = "projects/" + project_id + "/locations/global/catalogs/default_catalog/placements/<YOUR_SERVING_CONFIG_ID>"
するとsearch_response.redirect_uriにリダイレクトURLが設定されて返ってくる。
参照:リダイレクトコントロール
RESTで商品を検索してみる
リファレンスはこちら
在庫
ローカルインベントリ
フルフィルメント追加
フルフィルメントとはなんぞや。店舗受け取り、店舗宛て出荷、翌日配送などの在庫情報こと。
AddFulfillmentPlacesRequestクラスの
- product:商品Pの完全なリソース名
- type:店頭受け取りや当日配送などのカスタムタイプを含むフルフィルメントタイプ
- place_ids:このタイプ から削除するID
- allow_missing:
- true:商品が見つからない場合でも処理される
- false:商品が見つからない場合、NOT_FOUND エラーになる
を設定する。
それを引数にProductServiceClient().add_fulfillment_placesを呼び出す。
フルフィルメント削除
削除したいフィールドを設定したRemoveFulfillmentPlacesRequestクラスを作成する。
それを引数にProductServiceClient().remove_fulfillment_placesを呼び出す。
参考:remove_fulfillment_places.py
在庫設定
- name:商品の完全なリソース名
- price_info:価格情報
- fulfillment_info:フルフィルメント情報(店舗受け取り用の店舗IDや、様々な配送方法に対応する地域IDなど)
- availavility:商品のオンライン在庫状況(IN_STOCKとかOUT_OF_STOCKとか)
を設定する。
SetInventoryRequestの
- inventory:在庫情報 さっき作成したProductを設定する
- allow_missing:フルフィルメント追加のと同じ
- set_mask:商品情報のprice_info,availability,fulfillment_info,available_quantityなど、指定された商品のどの在庫フィールドを更新するかを設定
を設定する。
SetInventoryRequestを引数にProductServiceClient().set_inventoryを呼び出す。
Tips
- アクセストークンを知りたい時
gcloud auth print-access-token
- HTTPリクエストしたい時
curl -X GET
-H "Authorization: Bearer $(gcloud auth print-access-token)"
"URL"
- Placementに書くこと
;æprojects/{project_id}/locations/global/catalogs/{catalog_id}/placements/{placement_id}
- Project名などは環境変数から取得している。何が入っているか見たい時
printenv
- 商品カタログをインポートするとき
ProductServiceClient().import_productsを使う。