DATAES-40 added check for annotated field type to avoid unnecessary complex mapping

This commit is contained in:
Artur Konczak 2013-12-19 22:02:58 +00:00
parent 9b63f23f1b
commit 2a772d553a
4 changed files with 153 additions and 5 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.springframework.data.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.*;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.mapping.model.SimpleTypeHolder;
@ -25,6 +26,7 @@ import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Map;
@ -76,9 +78,9 @@ class MappingBuilder {
if (field.isAnnotationPresent(Transient.class)) {
continue;
}
if (isEntity(field) && !isInIgnoreFields(field)) {
}
if (isEntity(field) && !isInIgnoreFields(field) && !isAnnotated(field)) {
mapEntity(xContentBuilder, field.getType(), false, EMPTY, field.getName());
}
@ -105,6 +107,10 @@ class MappingBuilder {
}
private static boolean isAnnotated(java.lang.reflect.Field field) {
return field.getAnnotation(Field.class)==null && field.getAnnotation(MultiField.class)==null && field.getAnnotation(GeoPointField.class)==null;
}
private static void applyGeoPointFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field) throws IOException {
xContentBuilder.startObject(field.getName());
xContentBuilder.field(FIELD_TYPE, TYPE_VALUE_GEO_POINT)
@ -237,6 +243,7 @@ class MappingBuilder {
TypeInformation<?> actualType = typeInformation.getActualType();
boolean isComplexType = actualType == null ? false : !SIMPLE_TYPE_HOLDER.isSimpleType(actualType.getType());
return isComplexType && !actualType.isCollectionLike() && !Map.class.isAssignableFrom(typeInformation.getType());
//return isComplexType && !actualType.isCollectionLike() && !Map.class.isAssignableFrom(typeInformation.getType()) && !Number.class.isAssignableFrom(typeInformation.getType());
}
private static boolean isAnyPropertyAnnotatedAsField(java.lang.reflect.Field[] fields) {

View File

@ -0,0 +1,52 @@
package org.springframework.data.elasticsearch;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.math.BigDecimal;
@Document(indexName = "stock", type = "price", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1")
public class StockPrice {
@Id
private String id;
private String symbol;
@Field(type = FieldType.Double)
private BigDecimal price;
private StockPrice(){
//don't delete
}
public StockPrice(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}

View File

@ -0,0 +1,47 @@
package org.springframework.data.elasticsearch;
import org.springframework.data.elasticsearch.core.facet.ArticleEntity;
import org.springframework.data.elasticsearch.core.geo.AuthorMarkerEntity;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import java.math.BigDecimal;
/**
* User: dead
* Date: 09/12/13
* Time: 17:48
*/
public class StockPriceBuilder {
private StockPrice result;
public StockPriceBuilder(String id) {
result = new StockPrice(id);
}
public StockPriceBuilder symbol(String symbol) {
result.setSymbol(symbol);
return this;
}
public StockPriceBuilder price(BigDecimal price) {
result.setPrice(price);
return this;
}
public StockPriceBuilder price(double price) {
result.setPrice(new BigDecimal(price));
return this;
}
public StockPrice build() {
return result;
}
public IndexQuery buildIndex() {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(result.getId());
indexQuery.setObject(result);
return indexQuery;
}
}

View File

@ -4,15 +4,22 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.SampleTransientEntity;
import org.springframework.data.elasticsearch.SimpleRecursiveEntity;
import org.springframework.data.elasticsearch.*;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
/**
* @author Stuart Stevenson
@ -41,4 +48,39 @@ public class MappingBuilderTests {
assertThat(xContentBuilder.string(), is(expected));
}
@Test
public void shouldUseValueFromAnnotationType() throws IOException {
//Given
final String expected = "{\"mapping\":{\"properties\":{\"price\":{\"store\":false,\"type\":\"double\"}}}}";
//When
XContentBuilder xContentBuilder = MappingBuilder.buildMapping(StockPrice.class, "mapping", "id");
//Then
assertThat(xContentBuilder.string(), is(expected));
}
@Test
public void shouldAddStockPriceDocumentToIndex() throws IOException {
//Given
//When
elasticsearchTemplate.deleteIndex(StockPrice.class);
elasticsearchTemplate.createIndex(StockPrice.class);
elasticsearchTemplate.putMapping(StockPrice.class);
String symbol = "AU";
double price = 2.34;
String id = "abc";
elasticsearchTemplate.index(new StockPriceBuilder(id).symbol(symbol).price(price).buildIndex());
elasticsearchTemplate.refresh(StockPrice.class, true);
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
List<StockPrice> result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class);
//Then
assertThat(result.size(), is(1));
StockPrice entry = result.get(0);
assertThat(entry.getSymbol(), is(symbol));
assertThat(entry.getPrice(), is(new BigDecimal(price)));
}
}