如何对 Spring 数据使用 Elasticsearch 建议?

How to use Elasticsearch suggestions with Spring data?

我已经能够通过使用 cURL 获得建议(参见代码块)。但我需要在我的代码中执行此操作,以便我可以使用我的自定义端点 TOMCAT_ROOT/suggest?q=el。 can/should 我如何使用 Spring 数据创建查询,以在 Java 代码中获得相同的结果。

我的es映射:

{
    "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
            }
        }
    }
}

我的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, String fieldId, Date createdOn, Date lastUpdatedOn, String code, Map<Language, String> translations, Suggest suggest) {
        super(id, fieldId, createdOn, lastUpdatedOn);
        this.code = code;
        this.translations = translations;
        this.suggest = suggest;

    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Map<Language, String> getTranslations() {
        return translations;
    }

    public void setTranslations(Map<Language, String> translations) {
        this.translations = translations;
    }

    public Suggest getSuggest() {
        return suggest;
    }

    public void setSuggest(Suggest suggest) {
        this.suggest = suggest;
    }
}

我的es建议查询:

{
    "suggestions": {
        "text": "el",
        "completion": {
            "field": "suggest",
            "size": "10",
            "fuzzy": {
                "fuzziness": "AUTO"
            }
        }
    }
}

我的查询结果:

{
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "suggestions": [{
        "text": "el",
        "offset": 0,
        "length": 2,
        "options": [{
            "text": "Electrabel",
            "score": 1.0
        }, {
            "text": "Elision",
            "score": 1.0
        }]
    }]
}

我建议使用存储模板 (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-template-query.html#_stored_templates),它基本上可以让您将建议存储为 ES 中的模板。

然后通过引用模板名称并传递您的参数来执行 Java 代码 (https://www.elastic.co/guide/en/elasticsearch/client/java-api/1.6/java-search-template.html) 中的建议。

我设法通过使用 Spring 的 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;
    }
}

建议对象是根据弹性输出生成的

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"
})
public class Suggestions {

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("_shards")
    private be.smartask.service.model.Shards Shards;
    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("suggestions")
    private List<Suggestion> suggestions = new ArrayList<Suggestion>();
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    protected final static Object NOT_FOUND_VALUE = new Object();

    /**
     * 
     * (Required)
     * 
     * @return
     *     The Shards
     */
    @JsonProperty("_shards")
    public be.smartask.service.model.Shards getShards() {
        return Shards;
    }

    /**
     * 
     * (Required)
     * 
     * @param Shards
     *     The _shards
     */
    @JsonProperty("_shards")
    public void setShards(be.smartask.service.model.Shards Shards) {
        this.Shards = Shards;
    }

    /**
     * 
     * (Required)
     * 
     * @return
     *     The suggestions
     */
    @JsonProperty("suggestions")
    public List<Suggestion> getSuggestions() {
        return suggestions;
    }

    /**
     * 
     * (Required)
     * 
     * @param suggestions
     *     The suggestions
     */
    @JsonProperty("suggestions")
    public void setSuggestions(List<Suggestion> suggestions) {
        this.suggestions = suggestions;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    @SuppressWarnings({
        "unchecked"
    })
    protected boolean declaredProperty(String name, Object value) {
        if ("_shards".equals(name)) {
            if (value instanceof be.smartask.service.model.Shards) {
                setShards(((be.smartask.service.model.Shards) value));
            } else {
                throw new IllegalArgumentException(("property \"_shards\" is of type \"be.smartask.service.model.Shards\", but got "+ value.getClass().toString()));
            }
            return true;
        } else {
            if ("suggestions".equals(name)) {
                if (value instanceof List) {
                    setSuggestions(((List<Suggestion> ) value));
                } else {
                    throw new IllegalArgumentException(("property \"suggestions\" is of type \"java.util.List<be.smartask.service.model.Suggestion>\", but got "+ value.getClass().toString()));
                }
                return true;
            } else {
                return false;
            }
        }
    }

    @SuppressWarnings({
        "unchecked"
    })
    protected Object declaredPropertyOrNotFound(String name, Object notFoundValue) {
        if ("_shards".equals(name)) {
            return getShards();
        } else {
            if ("suggestions".equals(name)) {
                return getSuggestions();
            } else {
                return notFoundValue;
            }
        }
    }

    @SuppressWarnings({
        "unchecked"
    })
    public<T >T get(String name) {
        Object value = declaredPropertyOrNotFound(name, Suggestions.NOT_FOUND_VALUE);
        if (Suggestions.NOT_FOUND_VALUE!= value) {
            return ((T) value);
        } else {
            return ((T) getAdditionalProperties().get(name));
        }
    }

    @SuppressWarnings({
        "unchecked"
    })
    public void set(String name, Object value) {
        if (!declaredProperty(name, value)) {
            getAdditionalProperties().put(name, ((Object) value));
        }
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(Shards).append(suggestions).append(additionalProperties).toHashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof Suggestions) == false) {
            return false;
        }
        Suggestions rhs = ((Suggestions) other);
        return new EqualsBuilder().append(Shards, rhs.Shards).append(suggestions, rhs.suggestions).append(additionalProperties, rhs.additionalProperties).isEquals();
    }

}