Index Image using Our Data API
Overview
Built for scalability, ViSearch API enables fast and accurate searches on high volume of images. Before making your first image search, you need to prepare a list of images and index them into ViSearch by calling the insert
endpoint. Each image must have a distinct name (im_name
) which serves as this image's unique identifier and a publicly downloadable URL (im_url
). ViSearch will fetch and index your images from the given URLs.
In this guide, we will demonstrate how to index images, index images with metadata, update images, remove images and check indexing status using our Java SDK.
Index Images
To index your images, prepare a list of Images and call the insert
endpoint:
// the list of images to be indexed
List<Image> images = new ArrayList<Image>();
// the unique identifier of the image 'im_name'
String imName = "red_dress";
// the publicly downloadable url of the image 'im_url'
String imUrl = "http://mydomain.com/images/red_dress.jpg";
images.add(new Image(imName, imUrl));
// calls the insert endpoint to index the image
client.insert(images);
Each
insert
call to ViSearch accepts a maximum of 100 images. We recommend indexing your images in batches of 100 for optimized image indexing speed.
Each insert call will generate an insert transaction which contains an trans_id
. If there is any error during the insert
call, you can get the list of errors from the InsertTrans
object.
List<Image> images = new ArrayList<Image>();
String imName = "red_dress";
String imUrl = "http://mydomain.com/images/red_dress.jpg";
images.add(new Image(imName, imUrl));
// index the image and get the InsertTrans
InsertTrans trans = client.insert(images);
// check if the insert endpoint reports any errors
List<InsertError> errors = trans.getErrorList();
if (errors != null) {
System.out.println(trans.getTotal() + " succeed and " + errors.size() + " fail");
System.out.println("Errors list: ");
for (int i = 0; i < errors.size(); i++) {
System.out.println(errors.get(i));
}
}
Image with Metadata
Images usually come with descriptive text or numeric values as metadata, for example:
- title, description, category, brand, and price of an online shop listing image
- caption, tags, geo-coordinates of a photo
ViSearch combines the power of text search with image search. You can index your images with metadata, and leverage text based query and filtering for even more accurate image search results, for example:
- limit results within a price range
- limit results to certain tags, and some keywords in the captions
To index your images with metadata, first you need to configure the metadata schema in Dashboard. You can add or remove metadata keys, and modify the metadata types to suit your needs.
Let's assume you have the following metadata schema configured:
Name | Type | Searchable |
---|---|---|
title | string | true |
description | text | true |
price | float | true |
Then index your image with title, description and price:
List<Image> images = new ArrayList<Image>();
String imName = "vintage_wingtips";
String imUrl = "http://mydomain.com/images/vintage_wingtips.jpg";
// add metadata to your image
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("title", "Vintage Wingtips");
metadata.put("description", "A pair of high quality leather wingtips");
metadata.put("price", "100.0");
images.add(new Image(imName, imUrl, metadata));
client.insert(images);
Metadata keys are case-sensitive, and metadata without a matching key in the schema will not be processed by ViSearch. Make sure to configure metadata schema in Dashboard for all of your metadata keys.
Updating Images
If you need to update an image or its metadata, call the insert
endpoint with the same unique identifier of the image. ViSearch will fetch the image from the updated URL and index the new image, and update the metadata of the image. Please note that the metadata will not be overwritten but only be updated if the particular metadata field is provided.
List<Image> images = new ArrayList<Image>();
// the unique identifier 'im_name' of a previously indexed image
String imName = "vintage_wingtips";
// the new url of the image
String imUrl = "http://mydomain.com/images/vintage_wingtips_sale.jpg";
// update metadata of the image
Map<String, Object> metadata = new HashMap<String, Object>();
metadata.put("title", "Vintage Wingtips Sale");
metadata.put("price", "69.99");
images.add(new Image(imName, imUrl, metadata));
client.insert(images);
Each
insert
call to ViSearch accepts a maximum of 100 images. We recommend updating your images in batches of 100 for optimized image indexing speed.
Here is a list of errors that are returned from /insert API.
Error Code | Error Message |
---|---|
101 | Transaction not found with trans_id. |
102 | Image not found with im_name. |
103 | Exceeded maximum insert batch size of 100. |
104 | No image inserted. |
105 | Number of parameters for image exceeds maximum limit of 32. |
106 | {parameter} exceeds length limit. |
107 | Invalid im_name. |
108 | Missing im_url. |
109 | {field} should be of data type {type}. |
Removing Images
In case you decide to remove some of the indexed images, you can call the remove
endpoint with the list of unique identifier of the indexed images. ViSearch will then remove the specified images from the index.
// the list of unique identifiers 'im_name' of the images to be removed
List<String> removeList = new ArrayList<String>();
// removing previously indexed image "red_dress"
removeList.add("red_dress");
client.remove(removeList);
We recommend calling
remove
in batches of 100 images for optimized image indexing speed.
Check Indexing Status
The fetching and indexing process take time, and you may only search for images after their index are built. If you want to keep track of this process, you can call the insertStatus
endpoint with the image's transaction identifier.
List<Image> images = new ArrayList<Image>();
String imName = "vintage_wingtips";
String imUrl = "http://mydomain.com/images/vintage_wingtips.jpg";
images.add(new Image(imName, imUrl));
// index the image and get the InsertTrans
InsertTrans trans = client.insert(images);
InsertStatus status;
// check the status of indexing process while it is not complete
int percent = 0;
while (percent < 100) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
status = client.insertStatus(trans.getTransId());
percent = status.getProcessedPercent();
System.out.println(percent + "% complete");
}
int pageIndex = 1; // error page index always starts with 1
int errorPerPage = 10; // set error page limit
status = client.insertStatus(trans.getTransId(), pageIndex, errorPerPage);
System.out.println("Start time:" + status.getStartTime());
System.out.println("Update time:" + status.getUpdateTime());
System.out.println(status.getTotal() + " insertions with "
+ status.getSuccessCount() + " succeed and "
+ status.getFailCount() + " fail");
// print all the error messages if there are any
if (status.getFailCount() > 0) {
int totPageNumber = (int) Math.ceil(1.0 * status.getFailCount() / status.getErrorLimit());
for (pageIndex = 1; pageIndex <= totPageNumber; pageIndex++) {
status = client.insertStatus(trans.getTransId(), pageIndex, errorPerPage);
List<InsertError> errorList = status.getErrorList();
for (int errorIndex = 0; errorIndex < errorList.size(); errorIndex++) {
System.out.println("failure at page " + pageIndex
+ " with error message: " + errorList.get(errorIndex));
}
}
}
Three new error codes and corresponding descriptive error messages are added to help user understand why images are not inserted successfully. This error list advises the follow-up procedures for developers — check the validity of the image url or prepare images with required format and dimension for uploading:
Error Code | Error Message |
---|---|
201 | Could not download the image from im_url. |
202 | Unsupported image format. |
203 | Unsupported image dimension. |