Constructor.io provides search as a service that optimizes results using artificial intelligence (including natural language processing, re-ranking to optimize for conversions, and user personalization).
Full API documentation is available on Github Pages
Requesting results from your JVM based back-end can be useful in order to control result rendering logic on your server, or augment/hydrate results with data from another system. However, a back-end integration has additional requirements compared to a front-end integration. Please review the Additional Information For Backend Integrations article within the wiki for more detail.
- Follow the directions at Jitpack.io to add the client to your project.
- Retrieve your autocomplete token and key. You can find this at your Constructor.io dashboard.
- Create a new instance of the client.
ConstructorIOconstructor = newConstructorIO("apitoken", "apikey", true, null);A ConstructorItem contains all the information about a product or search suggestion. To add or replace a batch of items, you will need to provide an array of ConstructorItem's and their relevant Autocomplete Section.
// Create an array of itemsConstructorItem[] items = newConstructorItem[20];
items[0] = newConstructorItem("10001");
items[1] = newConstructorItem("10002");
...
items[19] = newConstructorItem("10003");
// Add or replace items in the Products sectionconstructor.createOrReplaceItems(items, "Products"); // (limit of 10,000 items)To update existing item(s), you will need to provide an array of ConstructorItem(s) and their relevant Autocomplete Section.
You can pass in an "onMissing" enum to tell the system how to handle updating items that don't exist (possible values are "FAIL" | "IGNORE" | "CREATE").
ConstructorItemitem = newConstructorItem("10001");
item.setSuggestedScore((float) 1337.00);
ConstructorItem[] items = { item };
// Update item(s) from the Products sectionconstructor.updateItems(items, "Products", false, null, CatalogRequest.OnMissing.IGNORE);To delete existing item(s), you will need to provide an array of ConstructorItem(s) and their relevant Autocomplete Section.
// Create an itemConstructorItemitem = newConstructorItem("10001");
ConstructorItem[] items = { item };
// Delete items from the Products sectionconstructor.deleteItems(items, "Products"); // (limit of 1,000 items)Retrieving your items.
ItemsRequestrequest = newItemsRequest();
ItemsResponseresponse = constructor.retrieveItems(request);You can also specify certain ids to retrieve.
ItemsRequestrequest = newItemsRequest();
request.setIds(Arrays.asList("10001", "10002"));
ItemsResponseresponse = constructor.retrieveItems(request);Retrieving your items as a JSON string.
ItemsRequestrequest = newItemsRequest();
Stringresponse = constructor.retrieveItemsAsJson(request);
JSONObjectjsonObj = newJSONObject(response);
JSONArrayitemsArray = jsonObj.getJSONArray("items");To replace or update your product catalog, you will need to create a CatalogRequest. In this request, you can specify the files you want to upload (items, variations, and item groups) and the section you want to upload to. You can also set a notification e-mail to be alerted when a file ingestion fails.
// Create a files map and add the relevant filesMap<String, File> files = newHashMap<String, File>();
files.put("items", newFile("src/test/resources/csv/items.csv"));
files.put("variations", newFile("src/test/resources/csv/variations.csv"));
files.put("item_groups", newFile("src/test/resources/csv/item_groups.csv"));
// Create a CatalogRequest with files to upload and the section to upload toCatalogRequestrequest = newCatalogRequest(files, "Products");
// Set a notification e-mailrequest.setNotificationEmail("integration@company.com");
// Set the force flag if the catalog should be processed even if it will invalidate a large number of existing itemsrequest.setForce(true)
// Send a request to replace the catalog (sync)constructor.replaceCatalog(request);
// Or send a request to update the catalog (delta)constructor.updateCatalog(request);To retrieve autocomplete results, you will need to create an AutocompleteRequest. In this request you can specify the number of results you want per autocomplete section. If the results are for a specific user, you can also create a UserInfo object, which will allow you to retrieve personalized results.
// Create an AutocompleteRequest with the term to request results forAutocompleteRequestrequest = newAutocompleteRequest("rain coat");
// Define the number of results to show per sectionMap<String, Integer> resultsPerSection = newHashMap<String, Integer>();
resultsPerSection.put("Products", Integer.valueOf(6));
resultsPerSection.put("Search Suggestions", Integer.valueOf(8));
request.setResultsPerSection(resultsPerSection);
// Create a UserInfo object with the session and unique device identifier (optional)UserInfouserInfo = newUserInfo(5, "device-id-1123123");
userInfo.setUserSegments(Arrays.asList("Desktop", "Chrome"));
// Add a variations map to request specific variation attributes as an array or object (optional)VariationsMapvariationsMap = newVariationsMap();
variationsMap.setdType(VariationsMap.Dtypes.array);
variationsMap.addGroupByRule("variation", "data.variation_id");
variationsMap.addValueRule("size", VariationsMap.AggregationTypes.first, "data.facets.size");
request.setVariationsMap(variationsMap);
// Request results as an objectAutocompleteResponseresponse = constructor.autocomplete(request, userInfo);
// Request results as a JSON stringStringresponse = constructor.autocompleteAsJSON(request, userInfo);To retrieve search results, you will need to create a SearchRequest. In this request you can specify the number of results you want per page, the page you want, sorting instructions, and also filter the results by category or facets. If the results are for a specific user, you can also create a UserInfo object, which will allow you to retrieve personalized results.
// Create a SearchRequest with the term to request results forSearchRequestrequest = newSearchRequest("peanut butter");
// Add in additional parametersrequest.setResultsPerPage(5);
request.setPage(1);
request.setGroupId("625");rrequest.setSortBy("Price");
request.setSortAscending(true);
request.getFacets().put("Brand", Arrays.asList("Jif"))
// Add the following paramaters to request for hidden fields or facetsrequest.getHiddenFields().add("hidden_price_field");
request.getHiddenFacets().add("hidden_brand_facet");
// Create a UserInfo object with the session and unique device identifier (optional)UserInfouserInfo = newUserInfo(5, "device-id-1123123");
userInfo.setUserSegments(Arrays.asList("Desktop", "Chrome"));
// Add a variations map to request specific variation attributes as an array or object (optional)VariationsMapvariationsMap = newVariationsMap();
variationsMap.setdType(VariationsMap.Dtypes.array);
variationsMap.addGroupByRule("variation", "data.variation_id");
variationsMap.addValueRule("size", VariationsMap.AggregationTypes.first, "data.facets.size");
request.setVariationsMap(variationsMap);
// Request results as an objectSearchResponseresponse = constructor.search(request, userInfo);
// Request results as a JSON stringStringresponse = constructor.searchAsJSON(request, userInfo);If you'd like to retrieve search results asynchronously, the above code can be modified slightly to utilize a callback methodology:
constructor.search(request, userInfo, newSearchCallback() {
@OverridepublicvoidonFailure(finalConstructorExceptionexception) {
// failure condition
}
@OverridepublicvoidonResponse(finalSearchResponseresponse) {
// success condition - data located within `response`
};
});To determine number of results coming from token matching algorithm vs. cognitive embeddings algorithm, you can use the ResultSources object under the response.
// Request results as an objectSearchResponseresponse = constructor.search(request, userInfo);
IntegerresultsFromTokenMatching = response.getResponse().getResultSources().getTokenMatch().getCount();
IntegerresultsFromCognitiveEmbeddings = response.getResponse().getResultSources().getEmbeddingsMatch().getCount();To retrieve search results for text that originated from speech transcription rather than typing, you will need to create a NaturalLanguageSearchRequest. In this request you can specify the number of results you want per page and the page you want. All other information is inferred from the text itself. If the results are for a specific user, you can also create a UserInfo object, which will allow you to retrieve personalized results. The response returned contains all of the same data points as a standard search response.
// Create a SearchRequest with the term to request results forNaturalLanguageSearchRequestrequest = newNaturalLanguageSearchRequest("peanut butter");
// Add in additional parametersrequest.setResultsPerPage(5);
request.setPage(1);
// Create a UserInfo object with the session and unique device identifier (optional)UserInfouserInfo = newUserInfo(5, "device-id-1123123");
userInfo.setUserSegments(Arrays.asList("Desktop", "Chrome"));
// Request results as an objectSearchResponseresponse = constructor.naturalLanguageSearch(request, userInfo);
// Request results as a JSON stringStringresponse = constructor.naturalLanguageSearchAsJSON(request, userInfo);To retrieve browse results, you will need to create a BrowseRequest. When creating the BrowseRequest the filter name can be one of collection_id, group_id, or a facet name (i.e. Brand). In this request, you can also specify the number of results you want per page, the page you want, sorting instructions, and also filter the results by category or facets. If the results are for a specific user, you can also create a UserInfo object, which will allow you to retrieve personalized results.
// Create a BrowseRequest with the filter name and filter value to request results forBrowseRequestrequest = newBrowseRequest("group_id", "8193");
// Add in additional parametersrequest.setResultsPerPage(5);
request.setPage(1);
request.setGroupId("625");rrequest.setSortBy("Price");
request.setSortAscending(true);
request.getFacets().put("Brand", Arrays.asList("Jif"))
// Add the following paramaters to request for hidden fields or facetsrequest.getHiddenFields().add("hidden_price_field");
request.getHiddenFacets().add("hidden_brand_facet");
// Create a UserInfo object with the session and unique device identifier (optional)UserInfouserInfo = newUserInfo(5, "device-id-1123123");
userInfo.setUserSegments(Arrays.asList("Desktop", "Chrome"));
// Add a variations map to request specific variation attributes as an array or object (optional)VariationsMapvariationsMap = newVariationsMap();
variationsMap.setdType(VariationsMap.Dtypes.array);
variationsMap.addGroupByRule("variation", "data.variation_id");
variationsMap.addValueRule("size", VariationsMap.AggregationTypes.first, "data.facets.size");
request.setVariationsMap(variationsMap);
// Request results as an objectBrowseResponseresponse = constructor.browse(request, userInfo);
// Request results as a JSON stringStringresponse = constructor.browseAsJSON(request, userInfo);If you'd like to retrieve browse results asynchronously, the above code can be modified slightly to utilize a callback methodology:
constructor.browse(request, userInfo, newBrowseCallback() {
@OverridepublicvoidonFailure(finalConstructorExceptionexception) {
// failure condition
}
@OverridepublicvoidonResponse(finalBrowseResponseresponse) {
// success condition - data located within `response`
};
});To retrieve browse results for a supplied list of item ID's, you will need to create a BrowseItemsRequest. When creating the BrowseItemsRequest the ids parameter will be a list of item ID's. In this request, you can also specify the number of results you want per page, the page you want, sorting instructions, and also filter the results by category or facets. If the results are for a specific user, you can also create a UserInfo object, which will allow you to retrieve personalized results.
// Create a BrowseItemsRequest with the filter name and filter value to request results forBrowseItemsRequestrequest = newBrowseItemsRequest(Arrays.asList("t-shirt-xxl"));
// Add in additional parametersrequest.setResultsPerPage(5);
request.setPage(1);
request.setGroupId("625");rrequest.setSortBy("Price");
request.setSortAscending(true);
request.getFacets().put("Brand", Arrays.asList("Jif"))
// Add the following paramaters to request for hidden fields or facetsrequest.getHiddenFields().add("hidden_price_field");
request.getHiddenFacets().add("hidden_brand_facet");
// Create a UserInfo object with the session and unique device identifier (optional)UserInfouserInfo = newUserInfo(5, "device-id-1123123");
userInfo.setUserSegments(Arrays.asList("Desktop", "Chrome"));
// Request results as an objectBrowseResponseresponse = constructor.browseItems(request, userInfo);
// Request results as a JSON stringStringresponse = constructor.browseItemsAsJSON(request, userInfo);If you'd like to retrieve browse items results asynchronously, the above code can be modified slightly to utilize a callback methodology:
constructor.browseItems(request, userInfo, newBrowseCallback() {
@OverridepublicvoidonFailure(finalConstructorExceptionexception) {
// failure condition
}
@OverridepublicvoidonResponse(finalBrowseResponseresponse) {
// success condition - data located within `response`
};
});To retrieve recommendation results, you will need to create a RecommendationsRequest. In this request, you can also specify the number of results you want and the items (given the ids) that you want to retrieve recommendations for. If the results are for a specific user, you can also create a UserInfo object, which will allow you to retrieve personalized results.
// Create a RecommendationsRequest with the pod id to request results forRecommendationsRequestrequest = newRecommendationsRequest("pdp_complementary_items");
// Add in additional parametersrequest.setNumResults(5);
request.setItemIds(Arrays.asList("9838172"))
// Create a UserInfo object with the session and unique device identifier (optional)UserInfouserInfo = newUserInfo(5, "device-id-1123123");
userInfo.setUserSegments(Arrays.asList("Desktop", "Chrome"));
// Add a variations map to request specific variation attributes as an array or object (optional)VariationsMapvariationsMap = newVariationsMap();
variationsMap.setdType(VariationsMap.Dtypes.array);
variationsMap.addGroupByRule("variation", "data.variation_id");
variationsMap.addValueRule("size", VariationsMap.AggregationTypes.first, "data.facets.size");
request.setVariationsMap(variationsMap);
// Request results as an objectRecommendationsResponseresponse = constructor.recommendations(request, userInfo);
// Request results as a JSON stringStringresponse = constructor.recommendationsAsJSON(request, userInfo);To retrieve all tasks, you will need to create a AllTasksRequest. In this request you can also specify the page and number of results per page. The page and number of results per page will default to 1 and 20 respectively.
// Create a AllTasksRequest to request results forAllTasksRequestrequest = newAllTasksRequest();
// Add in additional parametersrequest.setPage(2);
request.setResultsPerPage(10);
//Request all tasks as an objectAllTasksResponseresponse = constructor.allTasks(request);
//Request all tasks as a JSON stringStringresponse = constructor.allTasksAsJSON(request);To retrieve a specific task with a task_id, you will need to create a TaskRequest.
// Create a TaskRequest with the task_id to retrieveTaskRequestrequest = newTaskRequest("12345");
//Request task as an objectTaskresponse = constructor.task(request);
//Request task as a JSON stringStringresponse = constructor.taskAsJSON(request);Sort options allow you to define custom sorting strategies for search and browse results. You can create, update, delete, and retrieve sort options for your catalog.
To create a new sort option, you will need to create a SortOption object with the required fields and wrap it in a SortOptionRequest.
// Create a SortOption with the required fieldsSortOptionsortOption = newSortOption("price", SortOption.SortOrder.ascending);
sortOption.setDisplayName("Price");
sortOption.setPathInMetadata("price_min");
sortOption.setHidden(false);
// Create a SortOptionRequest with the sort option and sectionSortOptionRequestrequest = newSortOptionRequest(sortOption, "Products");
// Create the sort optionStringresponse = constructor.createSortOption(request);To update an existing sort option (or create it if it doesn't exist), use the updateSortOption method. The sort option is identified by the combination of sortBy and sortOrder.
// Create a SortOption with updated fieldsSortOptionsortOption = newSortOption("price", SortOption.SortOrder.ascending);
sortOption.setDisplayName("Price (Low to High)");
sortOption.setPathInMetadata("price_min");
sortOption.setHidden(false);
sortOption.setPosition(1);
// Create a SortOptionRequestSortOptionRequestrequest = newSortOptionRequest(sortOption, "Products");
// Update the sort optionStringresponse = constructor.updateSortOption(request);To delete a sort option, you need to specify the sortBy and sortOrder fields that identify it.
// Delete a single sort option by sortBy and sortOrderStringresponse = constructor.deleteSortOption("price", SortOption.SortOrder.ascending, "Products");
// Or use the default section "Products"Stringresponse = constructor.deleteSortOption("price", SortOption.SortOrder.ascending);
// To delete multiple sort options at onceSortOption[] sortOptions = newSortOption[] {
newSortOption("price", SortOption.SortOrder.ascending),
newSortOption("relevance", SortOption.SortOrder.descending)
};
Stringresponse = constructor.deleteSortOptions(sortOptions, "Products");To retrieve all sort options for a section, you can use the retrieveSortOptions method. You can optionally filter by a specific sortBy field and control pagination.
// Retrieve all sort options for the default "Products" sectionSortOptionsResponseresponse = constructor.retrieveSortOptions();
// Retrieve sort options filtered by sortBy fieldSortOptionsResponseresponse = constructor.retrieveSortOptions("price");
// Advanced retrieval with pagination and filtersSortOptionGetRequestrequest = newSortOptionGetRequest();
request.setSection("Products");
request.setSortBy("price");
request.setPage(1);
request.setResultsPerPage(20);
SortOptionsResponseresponse = constructor.retrieveSortOptions(request);
// Access the resultsinttotalCount = response.getTotalCount();
List<SortOption> sortOptions = response.getSortOptions();
for (SortOptionoption : sortOptions) {
System.out.println(option.getDisplayName() + " - " + option.getSortBy() + " " + option.getSortOrder());
}Download the repository and run the following commands from ./constructorio-client
mvn clean # clean target directory
mvn install # installs dependencies
mvn test# run tests
mvn spotless:check # check lint
mvn spotless:apply # run lint
mvn jacoco:report # writes code coverage reports to ./target/site/jacoco
mvn javadoc:javadoc # generate docsTEST_REQUEST_API_KEY # autocomplete_key for the Client Library Integration Request (CRABS) Tests
TEST_CATALOG_API_KEY # autocomplete_key for the Client Library Integration Catalog Tests
TEST_API_TOKEN # API token for the tests