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.