Installation

There are two clients for Java, the native Elasticsearch library and Jest.

The native client is a transport client which means it joins the cluster as a node and talks to Elasticsearch over the internal transport protocol.

Jest on the other hand talks to Elasticsearch over the REST API which allows for the higher levels of security employed by Facetflow, and is therefore the client of choice for this tutorial.

To get started, install Jest by adding the following Maven dependency to your project.


<dependency>
    <groupId>io.searchbox</groupId>
    <artifactId>jest</artifactId>
    <version>0.1.1</version>
</dependency>


Connecting

To connect you will need your cluster URL and your API key. You can get both of these from your Facetflow Control Panel's Connection Details page.
The API key will serve as the username for the connection, so you will need to configure your URL like this:


String url = "https://apikey:@account.region.cloud.facetflow.io";


Now we can go ahead and create the client config, client factory and client object.

The client object should have a short lifetime and will be disposed of after we have executed all our requests, while the factory object has a long lifetime and should be used to efficiently create new client objects when needed. We'll also set the read timeout explicitly because the default can be a bit low for longer running requests such as bulk indexing.


HttpClientConfig clientConfig = new HttpClientConfig.Builder(url)
                                                    .multiThreaded(true)
                                                    .readTimeout(10000)
                                                    .build();




JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(clientConfig);




JestClient client = factory.getObject();


Indexing

You can index a document by building a Index action with your model, index name and type name.

Finally we call the client's execute method to send the request to Elasticsearch. We've chosen to refresh the index (refresh(true)) as part of the Index action so that we can search for the document immediately.

Manually refreshing the index is only recommended for testing purposes since it has performance implications.


Post post = new Post();
post.setId(1);
post.setUser("me");
post.setMessage("trying out facetflow");




Index index = new Index.Builder(post)
                       .index("my_index")
                       .type("posts")
                       .refresh(true)
                       .build();
client.execute(index);


The model we have used in this example is a simple POJO with an annotation on the field we wish to use as the document id.


public class Post {
    @JestId
    private int id;
    private String user;
    private String message;




    public int getId() {
        return id;
    }




    public void setId(int id) {
        this.id = id;
    }




    public String getUser() {
        return user;
    }




    public void setUser(String user) {
        this.user = user;
    }




    public String getMessage() {
        return message;
    }




    public void setMessage(String message) {
        this.message = message;
    }
}

Searching

Searching is done by building a Search action using the Search.Builder class. The query parameter is a string so you can either pass in the query JSON directly using Elasticsearch's Query DSL or you can construct it using Elasticsearch's native SearchSourceBuilder class. In this example we'll be doing the latter, which means we will need to add another Maven dependency for Elasticsearch to our project to get access to SearchSourceBuilder.


<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>1.0.1</version>
</dependency>


We're now good to go with building our query. In this case we are constructing a filtered query to demonstrate how you can easily combine queries and filters in Java.


SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(
    QueryBuilders.filteredQuery(
        QueryBuilders.queryString("trying out facetflow"), 
        FilterBuilders.termFilter("user", "me")));


We can now execute the search query and dispose of the client and return it to the pool.


Search search = new Search.Builder(searchSourceBuilder.toString())
                          .addIndex("my_index")
                          .addType("posts")
                          .build();
JestResult result = client.execute(search);
client.shutdownClient();


Finally we'll deserialise the result into our Post POJO and print the result to the console.


List<Post> sources = result.getSourceAsObjectList(Post.class);




for (Post source : sources) {
    System.out.println(source.getUser() + " -> " + source.getMessage());
}


With basic indexing and search working, feel free to dive into more details on the Jest API and the Elasticsearch API in their respective official guides.