DATAES-462 - Add support for mapping max score and document scores.

Original pull request: #207.
This commit is contained in:
xhaggi 2018-06-13 12:08:20 +02:00 committed by Oliver Gierke
parent 112600261d
commit d996406113
11 changed files with 212 additions and 35 deletions

View File

@ -0,0 +1,23 @@
package org.springframework.data.elasticsearch.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.data.annotation.ReadOnlyProperty;
/**
* Specifies that this field is used for storing the document score.
*
* @author Sascha Woo
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
@ReadOnlyProperty
public @interface Score {
}

View File

@ -54,6 +54,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
* @author Chris White * @author Chris White
* @author Mark Paluch * @author Mark Paluch
* @author Ilkang Na * @author Ilkang Na
* @author Sascha Woo
*/ */
public class DefaultResultMapper extends AbstractResultMapper { public class DefaultResultMapper extends AbstractResultMapper {
@ -82,6 +83,8 @@ public class DefaultResultMapper extends AbstractResultMapper {
@Override @Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) { public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
long totalHits = response.getHits().getTotalHits(); long totalHits = response.getHits().getTotalHits();
float maxScore = response.getHits().getMaxScore();
List<T> results = new ArrayList<>(); List<T> results = new ArrayList<>();
for (SearchHit hit : response.getHits()) { for (SearchHit hit : response.getHits()) {
if (hit != null) { if (hit != null) {
@ -91,14 +94,17 @@ public class DefaultResultMapper extends AbstractResultMapper {
} else { } else {
result = mapEntity(hit.getFields().values(), clazz); result = mapEntity(hit.getFields().values(), clazz);
} }
setPersistentEntityId(result, hit.getId(), clazz); setPersistentEntityId(result, hit.getId(), clazz);
setPersistentEntityVersion(result, hit.getVersion(), clazz); setPersistentEntityVersion(result, hit.getVersion(), clazz);
setPersistentEntityScore(result, hit.getScore(), clazz);
populateScriptFields(result, hit); populateScriptFields(result, hit);
results.add(result); results.add(result);
} }
} }
return new AggregatedPageImpl<T>(results, pageable, totalHits, response.getAggregations(), response.getScrollId()); return new AggregatedPageImpl<T>(results, pageable, totalHits, response.getAggregations(), response.getScrollId(),
maxScore);
} }
private <T> void populateScriptFields(T result, SearchHit hit) { private <T> void populateScriptFields(T result, SearchHit hit) {
@ -113,8 +119,8 @@ public class DefaultResultMapper extends AbstractResultMapper {
try { try {
field.set(result, searchHitField.getValue()); field.set(result, searchHitField.getValue());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: " throw new ElasticsearchException(
+ searchHitField.getValue(), e); "failed to set scripted field: " + name + " with value: " + searchHitField.getValue(), e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new ElasticsearchException("failed to access scripted field: " + name, e); throw new ElasticsearchException("failed to access scripted field: " + name, e);
} }
@ -178,9 +184,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
} }
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) { private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) { if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(clazz); ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(clazz);
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
@ -188,13 +192,11 @@ public class DefaultResultMapper extends AbstractResultMapper {
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id); persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);
} }
} }
} }
private <T> void setPersistentEntityVersion(T result, long version, Class<T> clazz) { private <T> void setPersistentEntityVersion(T result, long version, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) { if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz); ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
@ -207,4 +209,16 @@ public class DefaultResultMapper extends AbstractResultMapper {
} }
} }
} }
private <T> void setPersistentEntityScore(T result, float score, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(clazz);
ElasticsearchPersistentProperty scoreProperty = persistentEntity.getScoreProperty();
Class<?> type = scoreProperty.getType();
if (scoreProperty != null && (type == Float.class || type == Float.TYPE)) {
persistentEntity.getPropertyAccessor(result).setProperty(scoreProperty, score);
}
}
}
} }

View File

@ -0,0 +1,16 @@
package org.springframework.data.elasticsearch.core;
import org.springframework.data.domain.Page;
/**
* A score-aware page gaining information about max score.
*
* @param <T>
* @author Sascha Woo
*/
public interface ScoredPage<T> extends Page<T> {
float getMaxScore();
}

View File

@ -3,12 +3,14 @@ package org.springframework.data.elasticsearch.core.aggregation;
import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.elasticsearch.core.FacetedPage; import org.springframework.data.elasticsearch.core.FacetedPage;
import org.springframework.data.elasticsearch.core.ScoredPage;
import org.springframework.data.elasticsearch.core.ScrolledPage; import org.springframework.data.elasticsearch.core.ScrolledPage;
/** /**
* @author Petar Tahchiev * @author Petar Tahchiev
* @author Sascha Woo
*/ */
public interface AggregatedPage<T> extends FacetedPage<T>, ScrolledPage<T> { public interface AggregatedPage<T> extends FacetedPage<T>, ScrolledPage<T>, ScoredPage<T> {
boolean hasAggregations(); boolean hasAggregations();

View File

@ -15,9 +15,7 @@
*/ */
package org.springframework.data.elasticsearch.core.aggregation.impl; package org.springframework.data.elasticsearch.core.aggregation.impl;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.Aggregations;
@ -29,55 +27,77 @@ import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
* @author Petar Tahchiev * @author Petar Tahchiev
* @author Artur Konczak * @author Artur Konczak
* @author Mohsin Husen * @author Mohsin Husen
* @author Sascha Woo
*/ */
public class AggregatedPageImpl<T> extends FacetedPageImpl<T> implements AggregatedPage<T> { public class AggregatedPageImpl<T> extends FacetedPageImpl<T> implements AggregatedPage<T> {
private Aggregations aggregations; private Aggregations aggregations;
private Map<String, Aggregation> mapOfAggregations = new HashMap<>(); private String scrollId;
private String scrollId; private float maxScore;
public AggregatedPageImpl(List<T> content) { public AggregatedPageImpl(List<T> content) {
super(content); super(content);
} }
public AggregatedPageImpl(List<T> content, float maxScore) {
super(content);
this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, String scrollId) { public AggregatedPageImpl(List<T> content, String scrollId) {
super(content); super(content);
this.scrollId = scrollId; this.scrollId = scrollId;
} }
public AggregatedPageImpl(List<T> content, String scrollId, float maxScore) {
this(content, scrollId);
this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, pageable, total); super(content, pageable, total);
} }
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, float maxScore) {
super(content, pageable, total);
this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId) {
super(content, pageable, total); super(content, pageable, total);
this.scrollId = scrollId; this.scrollId = scrollId;
} }
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId, float maxScore) {
this(content, pageable, total, scrollId);
this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations) {
super(content, pageable, total); super(content, pageable, total);
this.aggregations = aggregations; this.aggregations = aggregations;
if (aggregations != null) {
for (Aggregation aggregation : aggregations) {
mapOfAggregations.put(aggregation.getName(), aggregation);
}
}
} }
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations, String scrollId) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations, float maxScore) {
super(content, pageable, total); this(content, pageable, total, aggregations);
this.aggregations = aggregations; this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations,
String scrollId) {
this(content, pageable, total, aggregations);
this.scrollId = scrollId; this.scrollId = scrollId;
if (aggregations != null) { }
for (Aggregation aggregation : aggregations) {
mapOfAggregations.put(aggregation.getName(), aggregation); public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations, String scrollId,
} float maxScore) {
} this(content, pageable, total, aggregations, scrollId);
this.maxScore = maxScore;
} }
@Override @Override
public boolean hasAggregations() { public boolean hasAggregations() {
return aggregations != null && mapOfAggregations.size() > 0; return aggregations != null;
} }
@Override @Override
@ -94,4 +114,9 @@ public class AggregatedPageImpl<T> extends FacetedPageImpl<T> implements Aggrega
public String getScrollId() { public String getScrollId() {
return scrollId; return scrollId;
} }
@Override
public float getMaxScore() {
return maxScore;
}
} }

View File

@ -16,6 +16,7 @@
package org.springframework.data.elasticsearch.core.mapping; package org.springframework.data.elasticsearch.core.mapping;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.lang.Nullable;
/** /**
* ElasticsearchPersistentEntity * ElasticsearchPersistentEntity
@ -23,6 +24,7 @@ import org.springframework.data.mapping.PersistentEntity;
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Mark Paluch * @author Mark Paluch
* @author Sascha Woo
*/ */
public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, ElasticsearchPersistentProperty> { public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, ElasticsearchPersistentProperty> {
@ -49,4 +51,22 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
String settingPath(); String settingPath();
boolean isCreateIndexAndMapping(); boolean isCreateIndexAndMapping();
/**
* Returns whether the {@link ElasticsearchPersistentEntity} has an score property. If this call returns
* {@literal true}, {@link #getScoreProperty()} will return a non-{@literal null} value.
*
* @return false when {@link ElasticsearchPersistentEntity} does not define a score property.
*/
boolean hasScoreProperty();
/**
* Returns the score property of the {@link ElasticsearchPersistentEntity}. Can be {@literal null} in case no score
* property is available on the entity.
*
* @return the score {@link ElasticsearchPersistentProperty} of the {@link PersistentEntity} or {@literal null} if not
* defined.
*/
@Nullable
ElasticsearchPersistentProperty getScoreProperty();
} }

View File

@ -23,12 +23,24 @@ import org.springframework.data.mapping.PersistentProperty;
* *
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Sascha Woo
*/ */
public interface ElasticsearchPersistentProperty extends PersistentProperty<ElasticsearchPersistentProperty> { public interface ElasticsearchPersistentProperty extends PersistentProperty<ElasticsearchPersistentProperty> {
String getFieldName(); String getFieldName();
/**
* Returns whether the current property is a <em>potential</em> score property of the owning
* {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity}
* implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should
* rather call {@link ElasticsearchPersistentEntity#isScoreProperty(PersistentProperty)} to determine whether the
* current property is the version property of that {@link ElasticsearchPersistentEntity} under consideration.
*
* @return
*/
boolean isScoreProperty();
public enum PropertyToFieldNameConverter implements Converter<ElasticsearchPersistentProperty, String> { public enum PropertyToFieldNameConverter implements Converter<ElasticsearchPersistentProperty, String> {
INSTANCE; INSTANCE;

View File

@ -18,7 +18,6 @@ package org.springframework.data.elasticsearch.core.mapping;
import static org.springframework.util.StringUtils.*; import static org.springframework.util.StringUtils.*;
import java.util.Locale; import java.util.Locale;
import java.util.Optional;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -28,12 +27,14 @@ import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Parent;
import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext; import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -43,6 +44,7 @@ import org.springframework.util.Assert;
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Mark Paluch * @author Mark Paluch
* @author Sascha Woo
*/ */
public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntity<T, ElasticsearchPersistentProperty> public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntity<T, ElasticsearchPersistentProperty>
implements ElasticsearchPersistentEntity<T>, ApplicationContextAware { implements ElasticsearchPersistentEntity<T>, ApplicationContextAware {
@ -59,6 +61,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
private String indexStoreType; private String indexStoreType;
private String parentType; private String parentType;
private ElasticsearchPersistentProperty parentIdProperty; private ElasticsearchPersistentProperty parentIdProperty;
private ElasticsearchPersistentProperty scoreProperty;
private String settingPath; private String settingPath;
private boolean createIndexAndMapping; private boolean createIndexAndMapping;
@ -150,6 +153,17 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
return createIndexAndMapping; return createIndexAndMapping;
} }
@Override
public boolean hasScoreProperty() {
return scoreProperty != null;
}
@Nullable
@Override
public ElasticsearchPersistentProperty getScoreProperty() {
return scoreProperty;
}
@Override @Override
public void addPersistentProperty(ElasticsearchPersistentProperty property) { public void addPersistentProperty(ElasticsearchPersistentProperty property) {
super.addPersistentProperty(property); super.addPersistentProperty(property);
@ -165,7 +179,21 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
} }
if (property.isVersionProperty()) { if (property.isVersionProperty()) {
Assert.isTrue(property.getType() == Long.class, "Version property should be Long"); Assert.isTrue(property.getType() == Long.class, "Version property must be of type Long!");
}
if (property.isScoreProperty()) {
ElasticsearchPersistentProperty scoreProperty = this.scoreProperty;
if (scoreProperty != null) {
throw new MappingException(
String.format("Attempt to add score property %s but already have property %s registered "
+ "as version. Check your mapping configuration!", property.getField(), scoreProperty.getField()));
}
Assert.isTrue(property.getType() == Float.class || property.getType() == Float.TYPE, "Score property must be of type float!");
this.scoreProperty = property;
} }
} }
} }

View File

@ -18,11 +18,13 @@ package org.springframework.data.elasticsearch.core.mapping;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.mapping.Association; import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.Lazy;
/** /**
* Elasticsearch specific {@link org.springframework.data.mapping.PersistentProperty} implementation processing * Elasticsearch specific {@link org.springframework.data.mapping.PersistentProperty} implementation processing
@ -30,12 +32,15 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Mark Paluch * @author Mark Paluch
* @author Sascha Woo
*/ */
public class SimpleElasticsearchPersistentProperty extends public class SimpleElasticsearchPersistentProperty extends
AnnotationBasedPersistentProperty<ElasticsearchPersistentProperty> implements ElasticsearchPersistentProperty { AnnotationBasedPersistentProperty<ElasticsearchPersistentProperty> implements ElasticsearchPersistentProperty {
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<>(); private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<>();
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<>(); private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<>();
private final Lazy<Boolean> isScore = Lazy.of(() -> isAnnotationPresent(Score.class));
static { static {
SUPPORTED_ID_TYPES.add(String.class); SUPPORTED_ID_TYPES.add(String.class);
@ -62,4 +67,9 @@ public class SimpleElasticsearchPersistentProperty extends
protected Association<ElasticsearchPersistentProperty> createAssociation() { protected Association<ElasticsearchPersistentProperty> createAssociation() {
return null; return null;
} }
@Override
public boolean isScoreProperty() {
return isScore.get();
}
} }

View File

@ -36,6 +36,8 @@ import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.sort.SortOrder;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Before; import org.junit.Before;
@ -1512,6 +1514,31 @@ public class ElasticsearchTemplateTests {
assertThat(page.getContent().get(0).getMessage(), is("ab")); assertThat(page.getContent().get(0).getMessage(), is("ab"));
} }
@Test // DATAES-462
public void shouldReturnScores() {
// given
List<IndexQuery> indexQueries = new ArrayList<>();
indexQueries.add(buildIndex(SampleEntity.builder().id("1").message("ab xz").build()));
indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build()));
indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac xz hi").build()));
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.refresh(SampleEntity.class);
// when
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(termQuery("message", "xz"))
.withSort(SortBuilders.fieldSort("message"))
.withTrackScores(true)
.build();
AggregatedPage<SampleEntity> page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
// then
assertThat(page.getMaxScore(), greaterThan(0f));
assertThat(page.getContent().get(0).getScore(), greaterThan(0f));
}
@Test @Test
public void shouldDoIndexWithoutId() { public void shouldDoIndexWithoutId() {

View File

@ -15,29 +15,29 @@
*/ */
package org.springframework.data.elasticsearch.entities; package org.springframework.data.elasticsearch.entities;
import java.lang.Double; import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import java.lang.Long;
import java.lang.Object;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version; import org.springframework.data.annotation.Version;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.annotations.ScriptedField;
import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
/** /**
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Chris White * @author Chris White
* @author Sascha Woo
*/ */
@Setter @Setter
@Getter @Getter
@NoArgsConstructor @NoArgsConstructor
@ -58,11 +58,11 @@ public class SampleEntity {
private Double scriptedRate; private Double scriptedRate;
private boolean available; private boolean available;
private String highlightedMessage; private String highlightedMessage;
private GeoPoint location; private GeoPoint location;
@Version @Version
private Long version; private Long version;
@Score
private float score;
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {