Skip to content

Commit 356aa22

Browse files
committed
feat(retail): add searchOffset, searchPagination, and searchRequest samples
This commit introduces new Node.js code samples for Vertex AI Search, including comprehensive Mocha tests and logic to handle root-level product IDs and async indexing.
1 parent cf020ea commit 356aa22

5 files changed

Lines changed: 405 additions & 0 deletions

File tree

retail/snippets/package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "node-snippets",
3+
"license": "Apache-2.0",
4+
"author": "Google LLC",
5+
"engines": {
6+
"node": ">=18.0.0"
7+
},
8+
"files": [
9+
"*.js"
10+
],
11+
"scripts": {
12+
"test": "c8 mocha test/*.test.js --timeout 180000"
13+
},
14+
"devDependencies": {
15+
"c8": "^10.1.3",
16+
"chai": "^4.5.0",
17+
"mocha": "^10.8.2"
18+
},
19+
"dependencies": {
20+
"@google-cloud/retail": "^4.3.0"
21+
}
22+
}

retail/snippets/searchOffset.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
// [START retail_v2_search_offset]
18+
const {SearchServiceClient} = require('@google-cloud/retail');
19+
20+
const client = new SearchServiceClient();
21+
22+
/**
23+
* Search for products with an offset using Vertex AI Search for commerce.
24+
* Performs a search request starting from a specified position.
25+
*
26+
* @param {string} projectId The Google Cloud project ID.
27+
* @param {string} placementId The placement name for the search.
28+
* @param {string} visitorId A unique identifier for the user.
29+
* @param {string} query The search term.
30+
* @param {number} offset The number of results to skip.
31+
*/
32+
async function searchOffset(projectId, placementId, visitorId, query, offset) {
33+
const placementPath = client.servingConfigPath(
34+
projectId,
35+
'global',
36+
'default_catalog',
37+
placementId
38+
);
39+
40+
const branchPath = client.branchPath(
41+
projectId,
42+
'global',
43+
'default_catalog',
44+
'default_branch'
45+
);
46+
47+
const request = {
48+
placement: placementPath,
49+
branch: branchPath,
50+
visitorId: visitorId,
51+
query: query,
52+
pageSize: 10,
53+
offset: offset,
54+
};
55+
56+
try {
57+
// Set {autoPaginate: false} to manually control the pagination
58+
const [results] = await client.search(request, {autoPaginate: false});
59+
console.log(`--- Results for offset: ${offset} ---`);
60+
for (const result of results) {
61+
console.log(`Product ID: ${result.id}`);
62+
console.log(`Title: ${result.product.title}`);
63+
console.log(`Scores: ${JSON.stringify(result.modelScores || {})}`);
64+
}
65+
} catch (error) {
66+
console.error(`Error searching using offset: ${error.message}`);
67+
}
68+
}
69+
70+
// [END retail_v2_search_offset]
71+
module.exports = {searchOffset};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
// [START retail_v2_search_pagination]
18+
const {SearchServiceClient} = require('@google-cloud/retail');
19+
20+
const client = new SearchServiceClient();
21+
22+
/**
23+
* Search for products with pagination using Vertex AI Search for commerce.
24+
* Performs a search request, then uses the next_page_token to get the next page.
25+
*
26+
* @param {string} projectId - The Google Cloud project ID.
27+
* @param {string} placementId - The placement name for the search.
28+
* @param {string} visitorId - A unique identifier for the user.
29+
* @param {string} query - The search term.
30+
*/
31+
async function searchPagination(projectId, placementId, visitorId, query) {
32+
const placementPath = client.servingConfigPath(
33+
projectId,
34+
'global',
35+
'default_catalog',
36+
placementId
37+
);
38+
39+
const branchPath = client.branchPath(
40+
projectId,
41+
'global',
42+
'default_catalog',
43+
'default_branch'
44+
);
45+
46+
// First page request
47+
const firstRequest = {
48+
placement: placementPath,
49+
branch: branchPath,
50+
visitorId: visitorId,
51+
query: query,
52+
pageSize: 5,
53+
};
54+
55+
try {
56+
// Set {autoPaginate: false} to manually control the pagination
57+
// and extract the raw response which contains the next_page_token.
58+
const [firstPageResults, , firstRawResponse] = await client.search(
59+
firstRequest,
60+
{autoPaginate: false}
61+
);
62+
63+
console.log('--- First Page ---');
64+
for (const result of firstPageResults) {
65+
console.log(`Product ID: ${result.id}`);
66+
}
67+
68+
const nextPageToken = firstRawResponse.nextPageToken;
69+
70+
if (nextPageToken) {
71+
// Second page request using pageToken
72+
const secondRequest = {
73+
placement: placementPath,
74+
branch: branchPath,
75+
visitorId: visitorId,
76+
query: query,
77+
pageSize: 5,
78+
pageToken: nextPageToken,
79+
};
80+
81+
const [secondPageResults] = await client.search(secondRequest, {
82+
autoPaginate: false,
83+
});
84+
85+
console.log('--- Second Page ---');
86+
for (const result of secondPageResults) {
87+
console.log(`Product ID: ${result.id}`);
88+
}
89+
} else {
90+
console.log('No more pages.');
91+
}
92+
} catch (error) {
93+
console.error('Failed to complete paginated search:', error);
94+
}
95+
}
96+
// [END retail_v2_search_pagination]
97+
98+
module.exports = {searchPagination};

retail/snippets/searchRequest.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// [START retail_v2_search_request]
16+
const {SearchServiceClient} = require('@google-cloud/retail');
17+
18+
const client = new SearchServiceClient();
19+
20+
/**
21+
* Search for products using Vertex AI Search for commerce.
22+
*
23+
* Performs a search request for a specific placement.
24+
* Handles both text search (using query) and browse search (using pageCategories).
25+
*
26+
* @param {string} projectId - The Google Cloud project ID.
27+
* @param {string} placementId - The placement name for the search.
28+
* @param {string} visitorId - A unique identifier for the user.
29+
* @param {string} query - The search term for text search.
30+
* @param {string[]} pageCategories - The categories for browse search.
31+
*/
32+
async function searchRequest(
33+
projectId,
34+
placementId,
35+
visitorId,
36+
query = '',
37+
pageCategories = []
38+
) {
39+
const placementPath = client.servingConfigPath(
40+
projectId,
41+
'global',
42+
'default_catalog',
43+
placementId
44+
);
45+
46+
const branchPath = client.branchPath(
47+
projectId,
48+
'global',
49+
'default_catalog',
50+
'default_branch'
51+
);
52+
53+
const request = {
54+
placement: placementPath,
55+
branch: branchPath,
56+
visitorId: visitorId,
57+
query: query,
58+
pageCategories: pageCategories,
59+
pageSize: 10,
60+
};
61+
62+
try {
63+
// Set {autoPaginate: false} to manually control the pagination
64+
const [results] = await client.search(request, {autoPaginate: false});
65+
console.log('--- Search Results ---');
66+
for (const result of results) {
67+
console.log(`Product ID: ${result.id}`);
68+
console.log(` Name: ${result.product.name}`);
69+
console.log(` Scores: ${JSON.stringify(result.modelScores || {})}`);
70+
}
71+
} catch (error) {
72+
console.error(`Operation failed: ${error.message}`);
73+
}
74+
}
75+
76+
// [END retail_v2_search_request]
77+
78+
module.exports = {searchRequest};

0 commit comments

Comments
 (0)