Glenn Van Schil February 2016

How to use Elasticsearch suggestions with Spring data?

I'm already able to get suggestions by using cURL (see code blocks). But I need to do this in my code so I can use my custom endpoint TOMCAT_ROOT/suggest?q=el. How can/should I create a query, using Spring Data, to get the same result in Java code.

My es mapping:

{
    "textvalue": {
        "properties": {
            "id": {
                "type": "string",
                "index": "not_analyzed"
            },
            "fieldId": {
                "type": "string",
                "index": "not_analyzed"
            },
            "code": {
                "type": "string",
                "index": "not_analyzed"
            },
            "translations": {
                "type": "nested",
                "index": "not_analyzed"
            },
            "createdOn": {
                "type": "date",
                "format": "date_hour_minute_second"
            },
            "lastUpdatedOn": {
                "type": "date",
                "format": "date_hour_minute_second"
            },
            "suggest": {
                "type": "completion",
                "index_analyzer": "simple",
                "search_analyzer": "simple",
                "payloads": false
            }
        }
    }
}

My POJO:

package be.smartask.service.data;

import be.smartsearch.service.Language;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping;

import java.util.Date;
import java.util.Map;

/**
 * @author Glenn Van Schil
 *         Created on 26/01/2016
 */
@Document(indexName = "smartask", type = "textvalue")
@Mapping(mappingPath = "/es-mapping/textvalue-mapping.json")
public class TextValue extends Value {
    private String code;
    private Map<Language, String> translations;
    private Suggest suggest;

    public TextValue() {
    }

    public TextValue(String id,        

Answers


Bahaaldine Azarmi February 2016

I would recommend to use Store Template (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-template-query.html#_stored_templates), that basically lets you store your suggestion as a template in ES.

Then execute the suggestion from your Java code (https://www.elastic.co/guide/en/elasticsearch/client/java-api/1.6/java-search-template.html) by referring the template name and passing your argument.


Glenn Van Schil February 2016

I managed to do this by using Spring's RestTemplate

package be.smartask.service.suggestions;


import be.smartask.service.model.Suggestions;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @author Glenn Van Schil
 *         Created on 8/02/2016
 */
@Service
public class SuggestionService {

    public Suggestions getSuggestions(String word) {

        String uri = "http://localhost:9200/smartask/_suggest";
        String json = "{\"suggestions\":{\"text\":\"" + word + "\",\"completion\":{\"field\":\"suggest\",\"size\":\"10\",\"fuzzy\":{\"fuzziness\":\"AUTO\"}}}}";
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        Suggestions response = restTemplate.postForObject(uri, json, Suggestions.class);
        return response;
    }
}

The Suggestions object is generated based on elastics output

package be.smartask.service.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "_shards",
    "suggestions"
})
p 

Post Status

Asked in February 2016
Viewed 2,243 times
Voted 9
Answered 2 times

Search




Leave an answer