Dies ist die Dokumentation für Recommendations AI, Retail Search und die neue Retail Console. Wenn Sie Retail Search in der eingeschränkten GA-Phase nutzen möchten, wenden Sie sich an den Cloud-Vertrieb.

Wenn Sie Recommendations AI nur verwenden, bleiben Sie in der Recommendations-Konsole und sehen Sie sich die Dokumentation zu Recommendations AI an.

Inventar für Retail Search aktualisieren

Während die Product-Methoden zum Erstellen, Lesen, Aktualisieren und Löschen (CRUD) verwendet werden, um die Attribute eines Product umfassend zu ändern, gibt es eine Reihe von Product-Methoden, die wird für die Aktualisierung von inventarspezifischen Feldern mit unterschiedlichem Detaillierungsgrad verwendet. Die folgenden Product-Felder gelten als Inventarfelder:

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

Methoden zur Inventaraktualisierung

Änderungen an den Inventarinformationen eines Produkts können wesentlich häufiger erfolgen als Änderungen an seinen Kataloginformationen. Daher steht ein spezieller Satz von Methoden zur Verfügung, um große Mengen an inventarspezifischen Updates zu bewältigen. Diese Methoden sind asynchron aufgrund von nachgelagerten Optimierungen, die Hunderte von gleichzeitigen Aktualisierungen pro Produkt unterstützen, ohne die Leistung zu beeinträchtigen.

Inkrementelle Aktualisierungen

fulfillment_info wird häufig verwendet, um die Verfügbarkeit der Auftragsausführung auf Standortebene für eine Product zu codieren. In einigen Fällen kann sich die Verfügbarkeit der Auftragsausführung für bestimmte Orte ändern und Sie können Aktualisierungen festlegen, die diese Änderung beschreiben, anstatt die Methode UpdateProduct zu verwenden, um die Informationen zur Auftragsausführung des gesamten Produkts noch einmal anzugeben.

In solchen Fällen können Sie mit den Methoden AddFulfillmentPlaces und RemoveFulfillmentPlaces die Auftragsausführungsänderungen eines Produkts schrittweise aktualisieren, je nachdem, welche Orts-IDs für einen bestimmten Auftragsausführungstyp hinzugefügt oder entfernt werden.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Retail finden Sie unter Retail-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Retail Java API.

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
  }
  

Dieses Beispiel AddFulfillmentPlacesRequest fügt den Typ der Auftragsausführung "pickup-in- store" hinzu, um die IDs "store0" und "store1" für das angegebene Produkt zu platzieren. Da AddFulfillmentPlacesRequest.allow_missing auf "true" gesetzt ist, werden die aktualisierten Inventarinformationen auch bei der Erstellung des Produkts gespeichert, auch wenn das Produkt noch nicht vorhanden ist. Die Aktualisierung ist mit einem Zeitstempel versehen, der mit AddFulfillmentPlacesRequest.add_time versehen ist, um zu verhindern, dass veraltete Aktualisierungen den Auftragsausführungsstatus dieser Orts-IDs überschreiben. Diese Features werden in den folgenden Abschnitten ausführlicher behandelt.

Das Verhalten ist bei RemoveFulfillmentPlacesRequest identisch und das Schema ist sehr ähnlich.

Nicht inkrementelle Aktualisierungen

price_info, availability und available_quantity können nicht schrittweise aktualisiert werden, da sie Informationen zu Inventar auf Produktebene darstellen, anstatt Informationen auf Ortsebene zu verwenden. Darüber hinaus ist es möglicherweise wünschenswert, nicht inkrementelle Aktualisierungen an fulfillment_info vorzunehmen, anstatt nur inkrementelle Änderungen. In solchen Fällen wird die Methode SetInventory empfohlen.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Retail finden Sie unter Retail-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Retail Java API.

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
  }
  

In dieser Anfrage sind die SetInventoryRequest.product.fulfillment_info-Felder vollständige Beschreibungen der zulässigen Orts-IDs jedes Auftragsausführungstyps im Gegensatz zu inkrementellen Spezifikationen. Die Aktualisierung von "same-day-delivery" gibt an, dass für diesen Typ der Auftragsausführung für dieses Produkt keine Orts-IDs zulässig sind. Alle anderen Auftragsausführungstypen werden in dieser Anfrage nicht aktualisiert.

Standardmäßig aktualisiert SetInventory alle Inventarfelder, wenn SetInventory.set_mask nicht festgelegt oder leer ist. Wenn die Maske nicht leer ist oder ein Inventarfeld nicht explizit in SetInventoryRequest.set_mask aufgeführt ist, wird jeder angegebene Wert für dieses Inventarfeld in der Aktualisierungsanfrage ignoriert.

Wie bei inkrementellen Aktualisierungen kann das Feld SetInventoryRequest.set_time verwendet werden, um eine Aktualisierungszeit festzulegen, die auf die letzte aufgezeichnete Aktualisierungszeit aller aktualisierten Inventarfelder zutrifft.

Zeitstempelschutz für Inventaraktualisierungen

Es gibt mehrere verschiedene Pfade zum Aktualisieren der Inventarfelder eines Produkts. Zum Schutz vor Out-of-Order-Aktualisierungen ist jedes Inventarfeld mit einer neuesten Aktualisierungszeit verknüpft.

Die letzte Aktualisierungszeit wird für price_info, availability, available_quantity und jedes Paar von (fulfillment_info.place_ids, fulfillment_info.type) aufgezeichnet.

Die Methoden AddFulfillmentPlaces, RemoveFulfillmentPlaces und SetInventory ermöglichen dem Aufrufer, eine Aktualisierungszeit der Anfrage. Diese Aktualisierungszeit wird mit der letzten Aktualisierungszeit für die relevanten Inventarfelder verglichen und die Aktualisierung wird nur dann durchgeführt, wenn die Aktualisierungszeit ausschließlich hinter der letzten Aktualisierungszeit liegt.

Beispiel: Für die Orts-ID "store1" ist der Auftragsausführungstyp "pickup-in- store" aktiviert, wobei die letzte aufgezeichnete Aktualisierungszeit auf Zeit T gesetzt ist. Wenn RemoveFulfillmentPlacesRequest.type = "pickup-in-store" und RemoveFulfillmentPlacesRequest.place_ids "store1" enthalten, wird in der Anfrage "pickup-in-store" nur dann aus "store1" gelöscht, wenn die RemoveFulfillmentPlacesRequest.remove_time hinter der Uhrzeit T liegt. Dasselbe gilt für AddFulfillmentPlacesRequests.

SetInventory funktioniert auf ähnliche Weise zum Aktualisieren von price_info, availability und available_quantity. Beim Aktualisieren von fulfillment_info wird ein SetInventoryRequest implizit aufgefordert, alle angegebenen Orts-IDs für einen bestimmten Auftragsausführungstyp hinzuzufügen und alle nicht angegebenen vorhandenen IDs zu entfernen.

Das heißt, wenn die SetInventoryRequest-Verarbeitung verarbeitet wird, wird die fulfillment_info-Aktualisierung implizit in eine AddFulfillmentPlacesRequest- und eine RemoveFulfillmentPlacesRequest-Datei für jeden angegebenen Auftragsausführungstyp umgewandelt. Das bedeutet, wenn ein vorhandener Ort "store1" mit Auftragsausführung "pickup-in-store" eine letzte Aktualisierungszeit T hat, die aktueller als SetInventoryRequest.set_time ist, dann wird das implizite Hinzufügen/Entfernen von "store1" und "pickup-in-store" nicht angewendet.

Inventarinformationen vorab laden

Bei jeder Inventaraktualisierungsmethode kann der Aufrufer allow_missing in der Anfrage festlegen. Wenn allow_missing auf "true" gesetzt ist, wird eine Inventaraktualisierung auf ein nicht vorhandenes Product verarbeitet, als wäre das Product gemäß den Methodenspezifikationen vorhanden. Die Inventarinformationen werden maximal zwei Tage lang aufbewahrt, wenn der entsprechende Product innerhalb dieses Zeitraums nicht über CreateProduct erstellt wird.

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;
}

Wann werden die Product-Methoden verwendet?

Obwohl es möglich ist, Inventarfelder mit den CRUD-Methoden des Produkts zu aktualisieren, sollte der Aufrufer explizit die Auswirkungen auf vorhandene oder bereits vorhandene Inventarinformationen kennen.

Dies sind synchrone Methoden, d. h., die nachgelagerten Optimierungen, die für Inventarmethoden verwendet werden, gelten nicht und können für häufige Inventaraktualisierungen kostspielig werden. Verwenden Sie nach Möglichkeit die oben genannten Methoden zur Inventaraktualisierung.

CreateProduct

Wenn CreateProduct mit festgelegten Inventarfeldern aufgerufen wird, überschreiben die angegebenen Werte in CreateProductRequest.product alle vorab geladenen Werte für diese jeweiligen Felder. Wenn keine Inventarfelder festgelegt sind, werden automatisch alle vorhandenen Inventarinformationen verwendet.

Darüber hinaus wird der letzte Aktualisierungszeitpunkt für die überschriebenen Inventarfelder auf den Zeitpunkt des Methodenaufrufs zurückgesetzt.

CreateProduct mit vorab geladenem Inventar

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
  }
}

In diesem Beispiel sind für das erstellte Produkt keine Inventarfelder festgelegt. Dies bedeutet, dass vorab geladene Inventarinformationen automatisch verwendet werden, wenn Sie sie mit den Methoden zur Inventaraktualisierung aktualisieren. Dies kann hilfreich sein, wenn Inventaraktualisierungen von Katalogaktualisierungen entkoppelt werden und eine neu erstellte Product-Synchronisierung mit vorhandenen Inventarinformationen synchronisiert werden soll.

CreateProduct mit explizitem Inventar

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"
    }
  }
}

In diesem Beispiel wird ein Product mit explizit festgelegten Inventarfeldern erstellt. Diese Felder überschreiben alle bereits vorhandenen Werte und ignorieren die letzte Aktualisierungszeit für die entsprechenden Felder. Daher ist für das neu erstellte Product garantiert die Verfügbarkeit auf OUT_OF_STOCK festgelegt und keine Orts-IDs unterstützen die Auftragsausführungstypen "pickup-in-store" und "same-day-delivery".

CreateProduct mit Inventarinformationen können nützlich sein, wenn Sie nicht sicher sind, ob alle vorab geladenen Inventarinformationen korrekt sind, und Sie das Inventar lieber explizit zum Zeitpunkt der Erstellung von Product festzulegen, um den Katalog und das Inventar vollständig zu synchronisieren.

UpdateProduct

Wenn UpdateProduct aufgerufen wird und die Feldmaske UpdateProductRequest.update_mask Inventarfelder enthält, überschreiben die in UpdateProductRequest.product angegebenen Werte alle vorab geladenen Werte für diese jeweiligen Felder.

Darüber hinaus wird der letzte Aktualisierungszeitpunkt für die überschriebenen Inventarfelder auf den Zeitpunkt des Methodenaufrufs zurückgesetzt.

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"
  }
}

Dieses Beispiel ähnelt dem Beispiel SetInventory, mit der Ausnahme, dass die Aktualisierung unabhängig von der letzten Aktualisierungszeit jedes Inventarfelds angewendet wird.

UpdateProduct für Inventar kann hilfreich sein, wenn eine vollständige Synchronisierung von Inventarinformationen erforderlich ist, ohne Zeitstempelschutz zu ignorieren.

Es ist zwar möglich, Inventarinformationen mit UpdateProduct vorab zu laden, indem Sie UpdateProductRequest.allow_missing auf true setzen, um ein Product-Upsert durchzuführen, in der Methode müssen jedoch bestimmte Katalogfelder festgelegt werden, z. B. UpdateProductRequest.product.title. Daher wird empfohlen, die Methoden zur Inventaraktualisierung zum Vorabladen von Anwendungsfällen zu verwenden.

DeleteProduct

Wenn DeleteProduct aufgerufen wird, werden alle vorhandenen Inventarinformationen für das Produkt DeleteProductRequest.name gelöscht, einschließlich aller Datensätze der letzten Aktualisierungszeit für jedes Inventarfeld.