Direct Integration

Requirements

  • Java with version >=1.8
  • around 200MB to 500MB additional Java Heapspace (depending on the amount of data it has to manage)
  • If a firewall is used, it needs to be configured to allow connections to the following HTTPS Endpoints https://query.searchhub.io/ and https://import.searchhub.io/

Maven Dependency

The SmartQuery library can be pulled as a maven dependency from our private repository https://nexus.commerce-experts.com/content/repositories/searchhub-external/.

<dependency>
    <groupId>io.searchhub</groupId>
    <artifactId>smartquery</artifactId>
    <version>1.0.5</version>
</dependency>

<!-- ... -->

<repository>
    <id>external-releases</id>
    <url>https://nexus.commerce-experts.com/content/repositories/searchhub-external/</url>
</repository>

Essential Usage

The library contains the following three central types:

Tenant
Simple POJO that represents a single data domain. (See the glossary about what a Tenant is.)
QueryMapper

The central component provided by the SmartQuery library is the QueryMapper. It provides query mappings with the method mapQuery.

QueryMapping mapQuery(String input):
 This method returns a query mapping, with the original user query, a mapped query and an optional redirect URL. A QueryMapping has some convenience methods to handle redirects and queries accordingly - refer to the Javadoc.
QueryMapperManager

This class is responsible to initialize and manage the QueryMappers for the required Tenants. It needs to be instantiated with the provided API key [3]. It’s important to use a single QueryMapperManager object and keep the reference to it since it will internally spawn and manage several threads to update the QueryMapper instances asynchronously. If not needed anymore, the close method should be called, to stop the internal update threads.

QueryMapper getQueryMapper(Tenant t):
 

The getQueryMapper method will always return the same instance of QueryMapper for the same given Tenant, so it’s not necessary to keep a reference of the QueryMapper. Keeping a reference of a QueryMapper instance isn’t a problem though since each QueryMapper will be updated in the background.

A non-existing tenant won’t cause an error but simply return a QueryMapper that always returns null.

[3]You’ll receive your personal API Key directly from us.

Usage Example

private QueryMapperManager qmManager = QueryMapperManager.builder()
                                         .apiToken("YourApiKey")
                                         .updateRate(360)               // optional
                                         .preloadTenants("example.com") // optional
                                         .build();

public void searchProcess(HttpServletRequest req, HttpServletResponse resp)
{
    // init search process...

    Tenant tenant = new Tenant("example", "com");
    QueryMapper qm = qmManager.getQueryMapper(tenant);

    String searchQuery = req.getParameter("q");

    QueryMapping mapping = qm.mapQuery(searchQuery);
    if (mapping.hasRedirect()) {
        resp.setHeader("Location", mapping.getRedirect());
        resp.setStatus(302);
        return;
    } else {
        searchQuery = mapping.getSearchQuery();
    }

    // continue with search process...
}

// It's recommended to bind the qmManager instance to your JVM's lifecycle
// and close the QueryMapperManager during shutdown.
// Internally a ScheduledExecutorService is used, that will be stopped then.
@PreDestroy
public void onJvmShutdown() {
    qmManager.close();
}

The Javadoc of the QueryMapperManager.builder() methods tell you more about the possible settings.

Monitoring

SmartQuery optionally exposes internal metrics using the Micrometer framework. If you’d like to get those metrics, add the wanted Micrometer connector to your dependencies and add the wanted MeterRegistry implementation.

// ...
MeterRegistry meterRegistry = getYourMeterRegistryInstance();

// example: to expose metrics over JMX create a JmxMeterRegistry
meterRegistry = new JmxMeterRegistry(JmxConfig.DEFAULT, Clock.SYSTEM);

// and add it to the QueryMapperManager.builder afterwards
queryMapperManagerBuilder.addMetricsRegistryAdapter(MeterRegistryAdapter.of(meterRegistry));

// ...

You will be able to track the following metrics:

smartquery.statsCollector.queue.size
The current number of items inside the transmission queue of the stats-collector. Since the queue size is limited to 500 entries per default, a higher value should never appear. Hitting that limits is an indicator of a broken connection to the stats API.
smartquery.statsCollector.bulk.size.count
smartquery.statsCollector.bulk.size.sum
smartquery.statsCollector.bulk.size.max
The stats-collector’s bulk size metrics describe, how big the bulks are that were sent to the search|hub stats API. With sum/count the average size can be calculated. Max is the biggest bulk since application start.
smartquery.statsCollector.fail.count.total
The total amount of failed transmissions, that were reported to the stats API.
smartquery.update.fail.count
The number of failed mapping update attempts for a certain tenant in a row. If an update succeeds, this value will be reset to “0”. If this value reaches “5”, that update process will be stopped and only started again, if mappings for the according tenant are requested again. This metric is tagged with the according tenant_name and tenant_channel.
smartquery.update.success.count.total
The total number of successful data updates per tenant. This metric is tagged with the according tenant_name and tenant_channel.
smartquery.mappings.size
The current number of raw mapping pairs per tenant. This metric is tagged with the according tenant_name and tenant_channel.
smartquery.mappings.age.seconds
That is the passed time, since the last successful mapping update. This metric is tagged with the according tenant_name and tenant_channel.