mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-05 10:12:33 +00:00
DATAES-462 - Add support for mapping max score and document scores.
Original pull request: #207.
This commit is contained in:
parent
112600261d
commit
d996406113
@ -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 {
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user