DATAES-50 - Added scripted field functionality
This commit is contained in:
committed by
Artur Konczak
parent
727cb5eb09
commit
d6603f8edf
@@ -0,0 +1,19 @@
|
||||
package org.springframework.data.elasticsearch.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author Ryan Murfitt
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Documented
|
||||
public @interface ScriptedField {
|
||||
|
||||
/**
|
||||
* (Optional) The name of the scripted field. Defaults to
|
||||
* the field name.
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
}
|
||||
@@ -37,7 +37,9 @@ import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHitField;
|
||||
import org.elasticsearch.search.facet.Facet;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
||||
import org.springframework.data.elasticsearch.core.facet.DefaultFacetMapper;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetResult;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
@@ -85,6 +87,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
|
||||
result = mapEntity(hit.getFields().values(), clazz);
|
||||
}
|
||||
setPersistentEntityId(result, hit.getId(), clazz);
|
||||
populateScriptFields(result, hit);
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
@@ -101,7 +104,31 @@ public class DefaultResultMapper extends AbstractResultMapper {
|
||||
return new FacetedPageImpl<T>(results, pageable, totalHits, facets);
|
||||
}
|
||||
|
||||
private <T> T mapEntity(Collection<SearchHitField> values, Class<T> clazz) {
|
||||
private <T> void populateScriptFields(T result, SearchHit hit) {
|
||||
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) {
|
||||
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {
|
||||
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class);
|
||||
if (scriptedField != null) {
|
||||
String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();
|
||||
SearchHitField searchHitField = hit.getFields().get(name);
|
||||
if (searchHitField != null) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
field.set(result, searchHitField.getValue());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: "
|
||||
+ searchHitField.getValue(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ElasticsearchException("failed to access scripted field: " + name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private <T> T mapEntity(Collection<SearchHitField> values, Class<T> clazz) {
|
||||
return mapEntity(buildJSONFromFields(values), clazz);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Mapping;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||
@@ -841,7 +842,15 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(searchQuery.getFacets())) {
|
||||
if (!searchQuery.getScriptFields().isEmpty()) {
|
||||
searchRequest.addField("_source");
|
||||
}
|
||||
|
||||
for (ScriptField scriptedField : searchQuery.getScriptFields()) {
|
||||
searchRequest.addScriptField(scriptedField.fieldName(), scriptedField.script(), scriptedField.params());
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(searchQuery.getFacets())) {
|
||||
for (FacetRequest facetRequest : searchQuery.getFacets()) {
|
||||
FacetBuilder facet = facetRequest.getFacet();
|
||||
if (facetRequest.applyQueryFilter() && searchQuery.getFilter() != null) {
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.elasticsearch.index.query.FilterBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
@@ -23,6 +26,7 @@ import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -37,6 +41,7 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
||||
private QueryBuilder query;
|
||||
private FilterBuilder filter;
|
||||
private List<SortBuilder> sorts;
|
||||
private final List<ScriptField> scriptFields = new ArrayList<ScriptField>();
|
||||
private List<FacetRequest> facets;
|
||||
private List<AbstractAggregationBuilder> aggregations;
|
||||
private HighlightBuilder.Field[] highlightFields;
|
||||
@@ -81,6 +86,17 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
||||
return highlightFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ScriptField> getScriptFields() { return scriptFields; }
|
||||
|
||||
public void setScriptFields(List<ScriptField> scriptFields) {
|
||||
this.scriptFields.addAll(scriptFields);
|
||||
}
|
||||
|
||||
public void addScriptField(ScriptField... scriptField) {
|
||||
scriptFields.addAll(Arrays.asList(scriptField));
|
||||
}
|
||||
|
||||
public void addFacet(FacetRequest facetRequest) {
|
||||
if (facets == null) {
|
||||
facets = new ArrayList<FacetRequest>();
|
||||
|
||||
@@ -41,6 +41,7 @@ public class NativeSearchQueryBuilder {
|
||||
|
||||
private QueryBuilder queryBuilder;
|
||||
private FilterBuilder filterBuilder;
|
||||
private List<ScriptField> scriptFields = new ArrayList<ScriptField>();
|
||||
private List<SortBuilder> sortBuilders = new ArrayList<SortBuilder>();
|
||||
private List<FacetRequest> facetRequests = new ArrayList<FacetRequest>();
|
||||
private List<AbstractAggregationBuilder> aggregationBuilders = new ArrayList<AbstractAggregationBuilder>();
|
||||
@@ -69,6 +70,11 @@ public class NativeSearchQueryBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public NativeSearchQueryBuilder withScriptField(ScriptField scriptField) {
|
||||
this.scriptFields.add(scriptField);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NativeSearchQueryBuilder addAggregation(AbstractAggregationBuilder aggregationBuilder) {
|
||||
this.aggregationBuilders.add(aggregationBuilder);
|
||||
return this;
|
||||
@@ -141,6 +147,9 @@ public class NativeSearchQueryBuilder {
|
||||
if (fields != null) {
|
||||
nativeSearchQuery.addFields(fields);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(scriptFields)) {
|
||||
nativeSearchQuery.setScriptFields(scriptFields);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(facetRequests)) {
|
||||
nativeSearchQuery.setFacets(facetRequests);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Ryan Murfitt
|
||||
*/
|
||||
public class ScriptField {
|
||||
private final String fieldName;
|
||||
private final String script;
|
||||
private final Map<String, Object> params;
|
||||
|
||||
public ScriptField(String fieldName, String script, Map<String, Object> params) {
|
||||
this.fieldName = fieldName;
|
||||
this.script = script;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String fieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public String script() {
|
||||
return script;
|
||||
}
|
||||
|
||||
public Map<String, Object> params() {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +44,7 @@ public interface SearchQuery extends Query {
|
||||
List<AbstractAggregationBuilder> getAggregations();
|
||||
|
||||
HighlightBuilder.Field[] getHighlightFields();
|
||||
|
||||
List<ScriptField> getScriptFields();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user