Skip to content

Commit 51c722e

Browse files
feat(retail): add Vertex AI Search for commerce snippets (#10252)
* feat(retail): add Vertex AI Search for commerce snippets * Clean up * Add search by categories * Remove dependency version * Add description to samples * Refactor deletion of products to test * Refactor method to wait for products to be ready * Fix lint issue * Use placementId variable * Fix lint issues * Add test for pagination with no results
1 parent 8601aa9 commit 51c722e

9 files changed

Lines changed: 794 additions & 0 deletions

File tree

retail/snippets/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Vertex AI Search for commerce Samples
2+
3+
This directory contains Java samples for [Vertex AI Search for commerce](https://cloud.google.com/retail/docs/search-basic#search).
4+
5+
## Prerequisites
6+
7+
To run these samples, you must have:
8+
9+
1. **A Google Cloud Project** with the [Vertex AI Search for commerce API](https://console.cloud.google.com/apis/library/retail.googleapis.com) enabled.
10+
2. **Vertex AI Search for commerce** set up with a valid catalog and serving configuration (placement).
11+
3. **Authentication**: These samples use [Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/provide-credentials-adc).
12+
- If running locally, you can set up ADC by running:
13+
```bash
14+
gcloud auth application-default login
15+
```
16+
4. **IAM Roles**: The service account or user running the samples needs the `roles/retail.viewer` (Retail Viewer) role or higher.
17+
18+
## Samples
19+
20+
- **[Search.java](src/main/java/com/example/search/Search.java)**: Basic search request showing both text search and browse search (using categories).
21+
- **[SearchPagination.java](src/main/java/com/example/search/SearchPagination.java)**: Shows how to use `next_page_token` to paginate through search results.
22+
- **[SearchOffset.java](src/main/java/com/example/search/SearchOffset.java)**: Shows how to use `offset` to skip a specified number of results.
23+
24+
## Documentation
25+
26+
For more information, see the [Vertex AI Search for commerce documentation](https://docs.cloud.google.com/retail/docs/search-basic#search).

retail/snippets/pom.xml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2026 Google LLC
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18+
xmlns="http://maven.apache.org/POM/4.0.0"
19+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<groupId>com.example.retail</groupId>
22+
<artifactId>retail-samples</artifactId>
23+
<version>1.0-SNAPSHOT</version>
24+
25+
<!--
26+
The parent pom defines common style checks and testing strategies for our samples.
27+
Removing or replacing it should not affect the execution of the samples in anyway.
28+
-->
29+
<parent>
30+
<artifactId>shared-configuration</artifactId>
31+
<groupId>com.google.cloud.samples</groupId>
32+
<version>1.2.2</version>
33+
</parent>
34+
35+
<properties>
36+
<maven.compiler.source>21</maven.compiler.source>
37+
<maven.compiler.target>21</maven.compiler.target>
38+
</properties>
39+
40+
<dependencyManagement>
41+
<dependencies>
42+
<dependency>
43+
<artifactId>libraries-bom</artifactId>
44+
<groupId>com.google.cloud</groupId>
45+
<scope>import</scope>
46+
<type>pom</type>
47+
<version>26.80.0</version>
48+
</dependency>
49+
</dependencies>
50+
</dependencyManagement>
51+
52+
<dependencies>
53+
<dependency>
54+
<groupId>com.google.cloud</groupId>
55+
<artifactId>google-cloud-retail</artifactId>
56+
</dependency>
57+
58+
<!-- Test dependencies -->
59+
<dependency>
60+
<artifactId>truth</artifactId>
61+
<groupId>com.google.truth</groupId>
62+
<scope>test</scope>
63+
<version>1.4.5</version>
64+
</dependency>
65+
<dependency>
66+
<groupId>org.junit.jupiter</groupId>
67+
<artifactId>junit-jupiter</artifactId>
68+
<version>5.14.3</version>
69+
<scope>test</scope>
70+
</dependency>
71+
</dependencies>
72+
</project>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2026 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.search;
18+
19+
// [START retail_v2_search_request]
20+
21+
import com.google.cloud.retail.v2.BranchName;
22+
import com.google.cloud.retail.v2.Product;
23+
import com.google.cloud.retail.v2.SearchRequest;
24+
import com.google.cloud.retail.v2.SearchResponse;
25+
import com.google.cloud.retail.v2.SearchResponse.SearchResult;
26+
import com.google.cloud.retail.v2.SearchServiceClient;
27+
import com.google.cloud.retail.v2.SearchServiceClient.SearchPagedResponse;
28+
import com.google.cloud.retail.v2.ServingConfigName;
29+
import java.io.IOException;
30+
import java.util.List;
31+
32+
public class Search {
33+
public static void main(String[] args) throws IOException {
34+
String projectId = "my-project-id";
35+
String placementId = "default_search";
36+
String visitorId = "my-visitor-id";
37+
String query = "my search query";
38+
List<String> categories = List.of("category");
39+
40+
search(projectId, placementId, visitorId, query, categories);
41+
}
42+
43+
/**
44+
* Search for products using Vertex AI Search for commerce.
45+
*
46+
* Performs a search request for a specific placement. Handles both text search (using query)
47+
* and browse search (using page_categories).
48+
*
49+
* @param projectId The Google Cloud project ID.
50+
* @param placementId The placement name for the search.
51+
* @param visitorId A unique identifier for the user.
52+
* @param query The search term for text search.
53+
* @param categories The categories for browse search.
54+
*/
55+
public static void search(
56+
String projectId, String placementId, String visitorId, String query, List<String> categories)
57+
throws IOException {
58+
try (SearchServiceClient searchServiceClient = SearchServiceClient.create()) {
59+
ServingConfigName placementName =
60+
ServingConfigName.of(projectId, "global", "default_catalog", placementId);
61+
BranchName branchName =
62+
BranchName.of(projectId, "global", "default_catalog", "default_branch");
63+
SearchRequest searchRequest =
64+
SearchRequest.newBuilder()
65+
.setPlacement(placementName.toString())
66+
.setBranch(branchName.toString())
67+
.setVisitorId(visitorId)
68+
.setQuery(query)
69+
.addAllPageCategories(categories)
70+
.setPageSize(10)
71+
.build();
72+
SearchPagedResponse response = searchServiceClient.search(searchRequest);
73+
74+
SearchResponse searchResponse = response.getPage().getResponse();
75+
76+
System.out.println("Found " + searchResponse.getResultsCount() + " results in current page");
77+
for (SearchResult searchResult : searchResponse.getResultsList()) {
78+
Product product = searchResult.getProduct();
79+
System.out.println("---- Search Result ----");
80+
System.out.println("Product Name: " + product.getName());
81+
}
82+
}
83+
}
84+
}
85+
// [END retail_v2_search_request]
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2026 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.search;
18+
19+
// [START retail_v2_search_offset]
20+
21+
import com.google.cloud.retail.v2.BranchName;
22+
import com.google.cloud.retail.v2.Product;
23+
import com.google.cloud.retail.v2.SearchRequest;
24+
import com.google.cloud.retail.v2.SearchResponse;
25+
import com.google.cloud.retail.v2.SearchResponse.SearchResult;
26+
import com.google.cloud.retail.v2.SearchServiceClient;
27+
import com.google.cloud.retail.v2.SearchServiceClient.SearchPagedResponse;
28+
import com.google.cloud.retail.v2.ServingConfigName;
29+
import java.io.IOException;
30+
31+
public class SearchOffset {
32+
public static void main(String[] args) throws IOException {
33+
String projectId = "my-project-id";
34+
String placementId = "default_search";
35+
String visitorId = "my-visitor-id";
36+
String query = "my search query";
37+
int offset = 10;
38+
39+
searchWithOffset(projectId, placementId, visitorId, query, offset);
40+
}
41+
42+
/**
43+
* Search for products with an offset using Vertex AI Search for commerce.
44+
*
45+
* Performs a search request starting from a specified position.
46+
*
47+
* @param projectId The Google Cloud project ID.
48+
* @param placementId The placement name for the search.
49+
* @param visitorId A unique identifier for the user.
50+
* @param query The search term for text search.
51+
* @param offset The number of results to skip.
52+
*/
53+
public static void searchWithOffset(
54+
String projectId, String placementId, String visitorId, String query, int offset)
55+
throws IOException {
56+
try (SearchServiceClient searchServiceClient = SearchServiceClient.create()) {
57+
ServingConfigName placementName =
58+
ServingConfigName.of(projectId, "global", "default_catalog", placementId);
59+
BranchName branchName =
60+
BranchName.of(projectId, "global", "default_catalog", "default_branch");
61+
SearchRequest searchRequest =
62+
SearchRequest.newBuilder()
63+
.setPlacement(placementName.toString())
64+
.setBranch(branchName.toString())
65+
.setVisitorId(visitorId)
66+
.setQuery(query)
67+
.setPageSize(10)
68+
.setOffset(offset)
69+
.build();
70+
SearchPagedResponse response = searchServiceClient.search(searchRequest);
71+
72+
SearchResponse searchResponse = response.getPage().getResponse();
73+
74+
System.out.println("Found " + searchResponse.getResultsCount() + " results in current page");
75+
for (SearchResult searchResult : searchResponse.getResultsList()) {
76+
Product product = searchResult.getProduct();
77+
System.out.println("---- Search Result ----");
78+
System.out.println("Product Name: " + product.getName());
79+
}
80+
}
81+
}
82+
}
83+
// [END retail_v2_search_offset]
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2026 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.search;
18+
19+
// [START retail_v2_search_pagination]
20+
21+
import com.google.cloud.retail.v2.BranchName;
22+
import com.google.cloud.retail.v2.Product;
23+
import com.google.cloud.retail.v2.SearchRequest;
24+
import com.google.cloud.retail.v2.SearchResponse.SearchResult;
25+
import com.google.cloud.retail.v2.SearchServiceClient;
26+
import com.google.cloud.retail.v2.SearchServiceClient.SearchPage;
27+
import com.google.cloud.retail.v2.SearchServiceClient.SearchPagedResponse;
28+
import com.google.cloud.retail.v2.ServingConfigName;
29+
import java.io.IOException;
30+
31+
public class SearchPagination {
32+
public static void main(String[] args) throws IOException {
33+
String projectId = "my-project-id";
34+
String placementId = "default_search";
35+
String visitorId = "my-visitor-id";
36+
String query = "my search query";
37+
int pageSize = 10;
38+
39+
searchWithPagination(projectId, placementId, visitorId, query, pageSize);
40+
}
41+
42+
/**
43+
* Search for products with pagination using Vertex AI Search for commerce.
44+
*
45+
* Performs a search request, then uses the next_page_token to get the next page.
46+
*
47+
* @param projectId The Google Cloud project ID.
48+
* @param placementId The placement name for the search.
49+
* @param visitorId A unique identifier for the user.
50+
* @param query The search term for text search.
51+
* @param pageSize The amount of results per page.
52+
*/
53+
public static void searchWithPagination(
54+
String projectId, String placementId, String visitorId, String query, int pageSize)
55+
throws IOException {
56+
try (SearchServiceClient searchServiceClient = SearchServiceClient.create()) {
57+
ServingConfigName placementName =
58+
ServingConfigName.of(projectId, "global", "default_catalog", placementId);
59+
BranchName branchName =
60+
BranchName.of(projectId, "global", "default_catalog", "default_branch");
61+
SearchRequest request =
62+
SearchRequest.newBuilder()
63+
.setPlacement(placementName.toString())
64+
.setBranch(branchName.toString())
65+
.setVisitorId(visitorId)
66+
.setQuery(query)
67+
.setPageSize(pageSize)
68+
.build();
69+
int currentPage = 0;
70+
while (true) {
71+
SearchPagedResponse response = searchServiceClient.search(request);
72+
73+
SearchPage page = response.getPage();
74+
currentPage++;
75+
System.out.println("\nResults of page number " + currentPage + ":");
76+
System.out.println(
77+
"Found " + page.getResponse().getResultsCount() + " results in current page");
78+
for (SearchResult searchResult : page.getResponse().getResultsList()) {
79+
Product product = searchResult.getProduct();
80+
System.out.println("---- Search Result ----");
81+
System.out.println("Product Name: " + product.getName());
82+
}
83+
84+
if (page.hasNextPage()) {
85+
request = request.toBuilder().setPageToken(page.getNextPageToken()).build();
86+
} else {
87+
System.out.println("\nNo more available pages.");
88+
break;
89+
}
90+
}
91+
}
92+
}
93+
}
94+
// [END retail_v2_search_pagination]

0 commit comments

Comments
 (0)