更新商家適用的 Vertex AI Search 廣告空間

Product 建立、讀取、更新和刪除 (CRUD) 方法可用於廣泛修改 Product 的屬性,但有一組 Product 方法可用於更新精細程度不一的特定目錄欄位。下列 Product 欄位視為目錄欄位:

  • Product.price_info
  • Product.availability
  • Product.available_quantity
  • Product.fulfillment_info

教學課程:設定庫存資訊

本教學課程說明如何使用 SetInventory 方法推送商品目錄更新內容,不必更新整項產品。


如要直接在 Cloud Shell 編輯器中按照逐步指南操作,請按一下「Guide me」(逐步引導)

逐步引導


教學課程:新增出貨地點

建議您改用 AddLocalInventories 方法,而非 AddFulfillmentPlacesAddLocalInventories 可達到相同結果,但能更精細地控管店面商品目錄資料的擷取作業。詳情請參閱 AddLocalInventories 說明文件

本教學課程說明如何使用 AddFulfillmentPlaces 方法更新產品出貨資訊。這樣一來,搜尋結果就能顯示產品供應情形,以及訂單是否可出貨。舉例來說,購物者在商店尋找藍色牛仔褲,但店內缺貨。只要這家商店或任何其他商店再次進貨,購物者就會看到更新資訊,並繼續下單。


如要直接在 Cloud Shell 編輯器中按照逐步指南操作,請按一下「Guide me」(逐步引導)

逐步引導


教學課程:移除出貨地點

建議您改用 RemoveLocalInventories 方法,而非 RemoveFulfillmentPlacesRmoveLocalInventories 可達到相同結果,但能更精細地控管店面商品目錄資料的擷取作業。詳情請參閱 RemoveLocalInventories 說明文件

本教學課程將說明如何使用 RemoveFulfillmentPlaces 方法更新產品出貨資訊。這樣一來,Vertex AI Search for Commerce 就能顯示產品缺貨和訂單無法出貨的最新資訊。這樣一來,搜尋結果就能顯示產品缺貨和無法出貨的最新消息。舉例來說,購物者在商店中尋找藍色牛仔褲,如果這間商店的牛仔褲缺貨,購物者會看到這項資訊,且無法繼續下單。


如要直接在 Cloud Shell 編輯器中按照逐步指南操作,請按一下「Guide me」(逐步引導)

逐步引導


商品目錄更新方法

與產品目錄資訊相比,產品的庫存資訊較常異動。因此,我們提供一組專用方法,可處理大量庫存專屬更新。這些方法具備非同步的特性,這是因為下游最佳化調整功能可以針對個別產品並行執行數百項更新作業,而且不會影響效能。

分批更新

請注意,建議按照店面商品目錄更新指南發布增量商品目錄更新。新版 API 方法可更精細地控管各個地點的商品目錄屬性。

fulfillment_info 通常用於編碼 Product 的地點層級出貨供應情形。在某些情況下,特定地點的出貨供應情形可能會變更,而你可能會決定發布描述這項變更的更新,而不是使用 UpdateProduct 方法重新指定整個產品的出貨資訊。

在這種情況下,您可以使用 AddFulfillmentPlacesRemoveFulfillmentPlaces 方法,根據指定出貨類型新增或移除的地點 ID,逐步更新產品的出貨資訊異動。

Java

如要瞭解如何安裝及使用商家適用的 Vertex AI Search 用戶端程式庫,請參閱商家適用的 Vertex AI Search 用戶端程式庫。 詳情請參閱 Vertex AI Search for commerce Java API 參考說明文件

如要向商家適用的 Vertex AI Search 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

public static AddFulfillmentPlacesResponse addFulfillmentPlaces(
    Product productToUpdate, String fulfillmentInfoType, ImmutableList<String> placeIds)
    throws IOException, InterruptedException, ExecutionException {
  ProductServiceClient productClient = getProductServiceClient();

  AddFulfillmentPlacesRequest request = AddFulfillmentPlacesRequest.newBuilder()
      .setProduct(productToUpdate.getName())
      .setType(fulfillmentInfoType)
      .addAllPlaceIds(placeIds)
      .setAddTime(Timestamps.fromMillis(System.currentTimeMillis()))
      .build();

  AddFulfillmentPlacesResponse response = productClient
      .addFulfillmentPlacesAsync(request).get();

  productClient.shutdownNow();
  productClient.awaitTermination(2, TimeUnit.SECONDS);

  return response;
}

Proto

  {
    product: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch/products/p123"
    type: "pickup-in-store"
    place_ids: "store0"
    place_ids: "store1"
    add_time: {
      seconds: 100
      nanos: 100
    }
    allow_missing: true
  }
  

這個範例會新增履單類型 AddFulfillmentPlacesRequest,為指定產品放置 ID "pickup-in-store""store0""store1"。由於 AddFulfillmentPlacesRequest.allow_missing 設為 true,即使產品尚不存在,系統也會儲存更新後的庫存資訊,待產品建立後再套用。更新會加上時間戳記 AddFulfillmentPlacesRequest.add_time,避免過時的更新覆寫這些地點 ID 的出貨狀態。以下各節將詳細說明這些功能。

RemoveFulfillmentPlacesRequest 的行為與 完全相同,結構定義也十分相似。

fulfillment_typesAddLocalInventoriesRemoveLocalInventories 更新時,會反映從每個地點 ID 到其支援的出貨類型清單的對應。當 AddFulfillmentPlacesRemoveFulfillmentPlaces 更新 fulfillment_info 時,會反映從各個特定出貨類型到支援各類型的地點 ID 清單的對應。這兩種 API 類型都會修改相同的基礎出貨資訊,而這兩種 API 類型的影響都會反映在 Product.fulfillment_info 中。

非增量更新

price_infoavailabilityavailable_quantity 無法以遞增方式更新,因為這些屬性代表產品層級的庫存,而非地點層級的資訊。此外,您可能希望向 fulfillment_info 發布非累加式更新,而非僅發布累加式變更。在這種情況下,建議使用 SetInventory 方法。

Java

如要瞭解如何安裝及使用商家適用的 Vertex AI Search 用戶端程式庫,請參閱商家適用的 Vertex AI Search 用戶端程式庫。 詳情請參閱 Vertex AI Search for commerce Java API 參考說明文件

如要向商家適用的 Vertex AI Search 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

public static SetInventoryResponse setInventoryWithMask(Product productToUpdate,
    FieldMask updateMask)
    throws IOException, ExecutionException, InterruptedException {
  ProductServiceClient productClient = getProductServiceClient();

  SetInventoryRequest request = SetInventoryRequest.newBuilder()
      .setInventory(productToUpdate)
      .setSetMask(updateMask)
      .setSetTime(Timestamps.fromMillis(System.currentTimeMillis()))
      .setAllowMissing(true)
      .build();

  SetInventoryResponse response = productClient.setInventoryAsync(request).get();

  productClient.shutdownNow();
  productClient.awaitTermination(2, TimeUnit.SECONDS);

  return response;
}

Proto

  {
    product: {
      name: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch/products/p123"
      availability: IN_STOCK
      fulfillment_info: {
        type: "pickup-in-store"
        place_ids: "store0"
        place_ids: "store1"
        place_ids: "store2"
        place_ids: "store3"
      }
      fulfillment_info: {
        type: "same-day-delivery"
      }
    }
    set_time: {
      seconds: 100
      nanos: 100
    }
    set_mask: {
      paths: "availability"
      paths: "fulfillment_info"
    }
    allow_missing: true
  }
  

在這個特定要求中,SetInventoryRequest.product.fulfillment_info 欄位是各項履行類型適用地點 ID 的完整說明, 而非增量規格。"same-day-delivery" 更新表示沒有任何地點 ID 符合這項產品的這類出貨類型資格。這項要求不會更新所有其他履行類型。因此,這個方法可用於只替換部分出貨類型的地點 ID,其他類型則不受影響。

根據預設,如果 SetInventory.set_mask 未設定或空白,SetInventory 會更新所有廣告空間欄位。如果遮罩不是空白,或 SetInventoryRequest.set_mask 中未明確列出任何目錄欄位,系統就會在更新要求中忽略該目錄欄位的任何指定值。

與漸進式更新相同,SetInventoryRequest.set_time 欄位可用於設定更新時間,該時間會與所有更新庫存欄位上次記錄的更新時間進行比較。

商品目錄更新的時間戳記保護措施

更新產品庫存欄位有多種不同方式,為避免更新順序有誤,每個庫存欄位都會與最新的更新時間相關聯。

系統會記錄 price_infoavailabilityavailable_quantity 和每組 (fulfillment_info.place_ids, fulfillment_info.type) 的最新更新時間。

呼叫端可使用 AddFulfillmentPlacesRemoveFulfillmentPlacesSetInventory 方法,指定發出要求時的更新時間。系統會比較這個更新時間與相關庫存欄位記錄的最近更新時間,且只有在更新時間嚴格晚於最近更新時間時,才會提交更新。

舉例來說,假設地點 ID "store1" 已啟用出貨類型 "pickup-in- store",且最後記錄的更新時間設為時間 T。如果 RemoveFulfillmentPlacesRequest.type = "pickup-in-store"RemoveFulfillmentPlacesRequest.place_ids 包含 "store1",則只有在 RemoveFulfillmentPlacesRequest.remove_time 晚於時間 T 時,要求才會從 "store1" 清除 "pickup-in-store"AddFulfillmentPlacesRequests 也是如此。

更新 price_infoavailabilityavailable_quantity 時,SetInventory 的運作方式類似。更新 fulfillment_info 時,SetInventoryRequest 會隱含要求為指定履行類型新增所有指定地點 ID,並移除所有未指定的現有地點 ID。

因此,當系統處理 SetInventoryRequest 時,fulfillment_info 更新會隱含轉換為每個指定出貨類型的 AddFulfillmentPlacesRequestRemoveFulfillmentPlacesRequest。也就是說,如果任何現有地點 "store1" 具有出貨地點 "pickup-in-store",且最後更新時間 TSetInventoryRequest.set_time 新,系統就不會對 "store1""pickup-in-store" 隱含新增/移除。

預先載入商品目錄資訊

呼叫者可透過任一項庫存更新方法,在要求中設定 allow_missing。如果 allow_missing 設為 true,系統會根據方法規格處理對不存在的 Product 進行的庫存更新,就好像 Product 存在一樣。如果未在時限內透過 CreateProduct 建立相應的 Product,系統最多只會保留兩天的商品目錄資訊。

Java

public static SetInventoryResponse setInventory(Product productToUpdate)
    throws IOException, ExecutionException, InterruptedException {
  ProductServiceClient productClient = getProductServiceClient();

  SetInventoryRequest request = SetInventoryRequest.newBuilder()
      .setInventory(productToUpdate)
      .setSetTime(Timestamps.fromMillis(System.currentTimeMillis()))
      .setAllowMissing(true)
      .build();

  SetInventoryResponse response = productClient.setInventoryAsync(request).get();

  productClient.shutdownNow();
  productClient.awaitTermination(2, TimeUnit.SECONDS);

  return response;
}

使用 Product 方法的時機

雖然可以使用產品 CRUD 方法更新商品目錄欄位,但呼叫端應明確瞭解對現有或先前商品目錄資訊的影響。

這些是同步方法,因此不適用於用於目錄方法的下游最佳化調整功能,而且如果頻繁更新目錄,依賴這些方法可能會很昂貴。請盡可能使用上述商品目錄更新方法。

CreateProduct

如果呼叫 CreateProduct 時已設定任何廣告空間欄位,CreateProductRequest.product 中提供的值會覆寫這些欄位的任何預先載入值。如未設定任何商品目錄欄位,系統會自動使用任何現有的商品目錄資訊。

此外,系統會將遭覆寫的庫存欄位最近更新時間,重設為方法呼叫時間。

CreateProduct (已預先載入廣告空間)

PROTO

{
  parent: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch"
  product_id: "p123"
  product: {
    name: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch/products/p123"
    title: "some product"
    type: VARIANT
  }
}

在本範例中,建立的產品未設定任何庫存欄位,這表示如果使用庫存更新方法更新,系統會自動使用任何預先載入的庫存資訊。如果目錄更新與商品目錄更新已分離,且您想讓新建立的 Product 與任何現有的商品目錄資訊同步,這項功能就非常實用。

CreateProduct (含明確廣告空間)

PROTO

{
  parent: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch"
  product_id: "p123"
  product: {
    name: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch/products/p123"
    title: "some product"
    type: VARIANT
    availability: OUT_OF_STOCK
    fulfillment_info: {
      type: "pickup-in-store"
    }
    fulfillment_info: {
      type: "same-day-delivery"
    }
  }
}

在本例中,系統會建立 Product,並明確設定目錄欄位。這些欄位會覆寫所有先前的值,並忽略對應欄位的最近更新時間。因此,新建立的 Product 保證會將供應情形設為 OUT_OF_STOCK,且地點 ID 不會支援出貨類型 "pickup-in-store""same-day-delivery"

CreateProduct,如果無法確定所有預先載入的商品目錄資訊是否正確,且偏好在建立 Product 時明確設定商品目錄,以完全同步處理目錄和商品目錄,這項功能就很有幫助。

UpdateProduct

如果叫用 UpdateProduct 且欄位遮罩 UpdateProductRequest.update_mask 包含任何目錄欄位,UpdateProductRequest.product 中提供的相應欄位值會覆寫所有預先載入的值。

此外,系統會將遭覆寫的庫存欄位最近更新時間,重設為方法呼叫時間。

PROTO

{
  product: {
    name: "projects/123/locations/global/catalogs/default_catalog/branches/default_branch/products/p123"
    availability: IN_STOCK
    fulfillment_info: {
      type: "pickup-in-store"
      place_ids: "store0"
      place_ids: "store1"
      place_ids: "store2"
      place_ids: "store3"
    }
    fulfillment_info: {
      type: "same-day-delivery"
    }
  }
  update_mask: {
    paths: "availability"
    paths: "fulfillment_info"
  }
}

這個範例與 SetInventory 範例非常相似,但無論各個目錄欄位的最新更新時間為何,系統都會套用更新。

UpdateProduct 適用於需要完整同步處理廣告空間資訊,但忽略時間戳記保護措施的情況。

雖然可以透過設定 UpdateProductRequest.allow_missingtrue 來執行 Product upsert,藉此使用 UpdateProduct 預先載入目錄資訊,但這種方法需要設定特定目錄欄位,例如 UpdateProductRequest.product.title。因此,建議您使用預先載入用途的目錄更新方法。

DeleteProduct

呼叫 DeleteProduct 時,系統會刪除 DeleteProductRequest.name 中指定產品的所有現有商品目錄資訊,包括每個商品目錄欄位最新更新時間的所有記錄。