1
0
mirror of synced 2026-05-31 16:43:22 +00:00

Compare commits

...

27 Commits

Author SHA1 Message Date
Mark Paluch a1d508c656 DATAES-448 - Release version 3.0.8 (Kay SR8). 2018-06-13 15:13:01 +02:00
Mark Paluch 04308394dd DATAES-448 - Prepare 3.0.8 (Kay SR8). 2018-06-13 15:12:06 +02:00
Mark Paluch be80d7eae4 DATAES-448 - Updated changelog. 2018-06-13 15:12:04 +02:00
Mark Paluch de1c28979d DATAES-447 - Updated changelog. 2018-06-13 15:02:00 +02:00
Oliver Gierke bd668e6c2a DATAES-460 - Avoid Netty 3 dependency.
We now use a custom TransportClient implementation that reflectively pulls in the Netty transport client plugins. The previously used PreBuiltTransportClient expects both the Netty3 and the Netty 4 variant to be available at runtime. We now explicitly exclude Netty 3 so that Spring Data Elasticsearch projects run on Netty 4 by default.

Users required to stay on Netty 3 can explicitly declared the now excluded dependency.

Related tickets: https://github.com/elastic/elasticsearch/issues/31240
2018-06-11 14:11:25 +02:00
Christoph Strobl ba899a0017 DATAES-440 - Updated changelog. 2018-05-17 10:32:58 +02:00
Ted Liang 8181c713c7 DATAES-312 - Fix NullHandling.NULLS_LAST in query.sort
Original pull request: #163
2018-05-17 09:45:10 +02:00
Nordine Bittich c6419a1f05 DATAES-420 - Analyzer of main field ignored when using @MultiField annotation 2018-05-17 09:45:04 +02:00
Mark Paluch 09ee8f9026 DATAES-437 - After release cleanups. 2018-05-08 15:04:29 +02:00
Mark Paluch 13cfb039b5 DATAES-437 - Prepare next development iteration. 2018-05-08 15:04:27 +02:00
Mark Paluch 4c9c03ac0b DATAES-437 - Release version 3.0.7 (Kay SR7). 2018-05-08 14:15:28 +02:00
Mark Paluch cd597f059e DATAES-437 - Prepare 3.0.7 (Kay SR7). 2018-05-08 14:14:33 +02:00
Mark Paluch 7cf251a24e DATAES-437 - Updated changelog. 2018-05-08 14:14:31 +02:00
Mark Paluch fe5426b870 DATAES-436 - Updated changelog. 2018-05-08 12:22:53 +02:00
xhaggi 01a37c4fc3 DATAES-437 - update version overview in README 2018-05-08 11:40:01 +02:00
xhaggi 021495580f DATAES-285 - fix broken tests after 4970783ca4 2018-05-08 10:50:37 +02:00
xhaggi 4970783ca4 DATAES-285 - Polishing
* drop superfluous class FieldIndex
* change FieldType text and keyword starting with capital letters

Original commit: 089d7746be
2018-05-08 10:15:38 +02:00
Chris White 5ac31b3d2b DATAES-198 - Fixed @Version annotation on fields. 2018-05-07 13:01:25 +02:00
xhaggi 71b2ffc128 DATAES-412 - only the last highlight field is added to SearchRequest 2018-05-07 11:44:16 +02:00
Oliver Gierke 2642836e4d DATAES-363 - Polishing.
Original pull request: #183.
2018-04-18 12:45:15 +02:00
Michael Wirth 849d7da652 DATAES-363 - Fixed CrudRepository.existsById(…) implementation.
Properly use Optional.isPresent() over a null check.

Original pull request: #183.
2018-04-18 12:45:13 +02:00
xhaggi 5e29b958e5 DATAES-438 - BACKPORT - get rid of deprecation warning because of invalid mapping for @Id
(cherry picked from commit b949daa)
2018-04-13 16:03:41 +01:00
Mark Paluch 1b1ef4b5f4 DATAES-427 - Updated changelog. 2018-04-13 15:11:31 +02:00
Artur Konczak 79636c2a29 DATAES-402 - fixed broken tests 2018-04-06 10:30:41 +02:00
Remco Zigterman 787fc897d3 DATAES-402 - fixing paging information 2018-04-06 10:30:31 +02:00
Mark Paluch 4bdaf039c2 DATAES-430 - After release cleanups. 2018-04-04 16:42:34 +02:00
Mark Paluch 35003bf942 DATAES-430 - Prepare next development iteration. 2018-04-04 16:42:32 +02:00
28 changed files with 693 additions and 156 deletions
+6 -11
View File
@@ -52,17 +52,12 @@ the appropriate dependency version.
</repository>
```
| spring data elasticsearch | elasticsearch |
|:-----------------------------------:|:-------------:|
| 3.0.0.RC2 | 5.5.0 |
| 3.0.0.M4 | 5.4.0 |
| 2.0.4.RELEASE | 2.4.0 |
| 2.0.0.RELEASE | 2.2.0 |
| 1.4.0.M1 | 1.7.3 |
| 1.3.0.RELEASE | 1.5.2 |
| 1.2.0.RELEASE | 1.4.4 |
| 1.1.0.RELEASE | 1.3.2 |
| 1.0.0.RELEASE | 1.1.1 |
| spring data elasticsearch | elasticsearch |
|:-------------------------:|:-------------:|
| 3.0.x | 5.5.0 |
| 2.1.x | 2.4.0 |
| 2.0.x | 2.2.0 |
| 1.3.x | 1.5.2 |
### ElasticsearchRepository
+13 -11
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.0.6.RELEASE</version>
<version>3.0.8.RELEASE</version>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.0.6.RELEASE</version>
<version>2.0.8.RELEASE</version>
</parent>
<name>Spring Data Elasticsearch</name>
@@ -21,7 +21,7 @@
<commonslang>2.6</commonslang>
<elasticsearch>5.5.0</elasticsearch>
<log4j>2.8.2</log4j>
<springdata.commons>2.0.6.RELEASE</springdata.commons>
<springdata.commons>2.0.8.RELEASE</springdata.commons>
<java-module-name>spring.data.elasticsearch</java-module-name>
</properties>
@@ -81,9 +81,19 @@
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty3-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
@@ -162,14 +172,6 @@
<scope>test</scope>
</dependency>
<dependency>
<!-- required by elasticsearch -->
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
@@ -1,26 +0,0 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.annotations;
/**
* @author Artur Konczak
* @author Mohsin Husen
* @author Alexander Volz
* @author Dennis Maaß
*/
public enum FieldIndex {
not_analyzed, analyzed, no
}
@@ -21,5 +21,17 @@ package org.springframework.data.elasticsearch.annotations;
* @author Artur Konczak
*/
public enum FieldType {
text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, keyword
Text,
Integer,
Long,
Date,
Float,
Double,
Boolean,
Object,
Auto,
Nested,
Ip,
Attachment,
Keyword
}
@@ -33,11 +33,15 @@ public @interface InnerField {
boolean index() default true;
DateFormat format() default DateFormat.none;
String pattern() default "";
boolean store() default false;
boolean fielddata() default false;
String searchAnalyzer() default "";
String indexAnalyzer() default "";
String analyzer() default "";
}
@@ -17,12 +17,29 @@ package org.springframework.data.elasticsearch.client;
import static org.apache.commons.lang.StringUtils.*;
import io.netty.util.ThreadDeathWatcher;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.reindex.ReindexPlugin;
import org.elasticsearch.join.ParentJoinPlugin;
import org.elasticsearch.percolator.PercolatorPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.mustache.MustachePlugin;
import org.elasticsearch.transport.Netty4Plugin;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,6 +47,7 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* TransportClientFactoryBean
@@ -88,7 +106,7 @@ public class TransportClientFactoryBean implements FactoryBean<TransportClient>,
protected void buildClient() throws Exception {
client = new PreBuiltTransportClient(settings());
client = new SpringDataTransportClient(settings());
Assert.hasText(clusterNodes, "[Assertion failed] clusterNodes settings missing.");
for (String clusterNode : split(clusterNodes, COMMA)) {
String hostName = substringBeforeLast(clusterNode, COLON);
@@ -153,4 +171,97 @@ public class TransportClientFactoryBean implements FactoryBean<TransportClient>,
public void setProperties(Properties properties) {
this.properties = properties;
}
/**
* Pretty exact copy of {@link PreBuiltTransportClient} except that we're inspecting the classpath for Netty
* dependencies to only include the ones available. {@link PreBuiltTransportClient} expects both Netty 3 and Netty 4
* to be present.
*
* @author Oliver Gierke
* @see https://github.com/elastic/elasticsearch/issues/31240
*/
@SuppressWarnings("unchecked")
private static class SpringDataTransportClient extends TransportClient {
/**
* Netty wants to do some unwelcome things like use unsafe and replace a private field, or use a poorly considered
* buffer recycler. This method disables these things by default, but can be overridden by setting the corresponding
* system properties.
*/
private static void initializeNetty() {
/*
* We disable three pieces of Netty functionality here:
* - we disable Netty from being unsafe
* - we disable Netty from replacing the selector key set
* - we disable Netty from using the recycler
*
* While permissions are needed to read and set these, the permissions needed here are innocuous and thus should simply be granted
* rather than us handling a security exception here.
*/
setSystemPropertyIfUnset("io.netty.noUnsafe", Boolean.toString(true));
setSystemPropertyIfUnset("io.netty.noKeySetOptimization", Boolean.toString(true));
setSystemPropertyIfUnset("io.netty.recycler.maxCapacityPerThread", Integer.toString(0));
}
@SuppressForbidden(reason = "set system properties to configure Netty")
private static void setSystemPropertyIfUnset(final String key, final String value) {
final String currentValue = System.getProperty(key);
if (currentValue == null) {
System.setProperty(key, value);
}
}
private static final List<String> OPTIONAL_DEPENDENCIES = Arrays.asList( //
"org.elasticsearch.transport.Netty3Plugin", //
"org.elasticsearch.transport.Netty4Plugin");
private static final Collection<Class<? extends Plugin>> PRE_INSTALLED_PLUGINS;
static {
initializeNetty();
List<Class<? extends Plugin>> plugins = new ArrayList<>();
boolean found = false;
for (String dependency : OPTIONAL_DEPENDENCIES) {
try {
plugins.add((Class<? extends Plugin>) ClassUtils.forName(dependency,
SpringDataTransportClient.class.getClassLoader()));
found = true;
} catch (ClassNotFoundException | LinkageError e) {}
}
Assert.state(found, "Neither Netty 3 or Netty 4 plugin found on the classpath. One of them is required to run the transport client!");
plugins.add(ReindexPlugin.class);
plugins.add(PercolatorPlugin.class);
plugins.add(MustachePlugin.class);
plugins.add(ParentJoinPlugin.class);
PRE_INSTALLED_PLUGINS = Collections.unmodifiableList(plugins);
}
public SpringDataTransportClient(Settings settings) {
super(settings, PRE_INSTALLED_PLUGINS);
}
@Override
public void close() {
super.close();
if (NetworkModule.TRANSPORT_TYPE_SETTING.exists(settings) == false
|| NetworkModule.TRANSPORT_TYPE_SETTING.get(settings).equals(Netty4Plugin.NETTY_TRANSPORT_NAME)) {
try {
GlobalEventExecutor.INSTANCE.awaitInactivity(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
try {
ThreadDeathWatcher.awaitInactivity(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}
@@ -39,6 +39,7 @@ import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPa
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
@@ -49,6 +50,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
* @author Petar Tahchiev
* @author Young Gu
* @author Oliver Gierke
* @author Chris White
* @author Mark Paluch
*/
public class DefaultResultMapper extends AbstractResultMapper {
@@ -88,6 +90,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
result = mapEntity(hit.getFields().values(), clazz);
}
setPersistentEntityId(result, hit.getId(), clazz);
setPersistentEntityVersion(result, hit.getVersion(), clazz);
populateScriptFields(result, hit);
results.add(result);
}
@@ -153,6 +156,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
T result = mapEntity(response.getSourceAsString(), clazz);
if (result != null) {
setPersistentEntityId(result, response.getId(), clazz);
setPersistentEntityVersion(result, response.getVersion(), clazz);
}
return result;
}
@@ -164,6 +168,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
if (!response.isFailed() && response.getResponse().isExists()) {
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
setPersistentEntityId(result, response.getResponse().getId(), clazz);
setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz);
list.add(result);
}
}
@@ -184,4 +189,20 @@ public class DefaultResultMapper extends AbstractResultMapper {
}
}
private <T> void setPersistentEntityVersion(T result, long version, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
// Only deal with Long because ES versions are longs !
if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) {
// check that a version was actually returned in the response, -1 would indicate that
// a search didn't request the version ids in the response, which would be an issue
Assert.isTrue(version != -1, "Version in response is -1");
persistentEntity.getPropertyAccessor(result).setProperty(versionProperty, version);
}
}
}
}
@@ -59,7 +59,9 @@ import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
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.suggest.SuggestBuilder;
import org.slf4j.Logger;
@@ -105,7 +107,10 @@ import static org.springframework.util.CollectionUtils.isEmpty;
* @author Young Gu
* @author Oliver Gierke
* @author Mark Janssen
* @author Chris White
* @author Mark Paluch
* @author Sascha Woo
* @author Ted Liang
*/
public class ElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware {
@@ -730,7 +735,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) {
SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices()))
.setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0);
.setTypes(toArray(query.getTypes()))
.setScroll(TimeValue.timeValueMillis(scrollTimeInMillis))
.setFrom(0)
.setVersion(true);
if(query.getPageable().isPaged()){
requestBuilder.setSize(query.getPageable().getPageSize());
@@ -875,9 +883,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
}
if (searchQuery.getHighlightFields() != null) {
HighlightBuilder highlightBuilder = new HighlightBuilder();
for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) {
searchRequest.highlighter(new HighlightBuilder().field(highlightField));
highlightBuilder.field(highlightField);
}
searchRequest.highlighter(highlightBuilder);
}
if (!isEmpty(searchQuery.getIndicesBoost())) {
@@ -975,7 +985,9 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
int startRecord = 0;
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(toArray(query.getIndices()))
.setSearchType(query.getSearchType()).setTypes(toArray(query.getTypes()));
.setSearchType(query.getSearchType())
.setTypes(toArray(query.getTypes()))
.setVersion(true);
if (query.getSourceFilter() != null) {
SourceFilter sourceFilter = query.getSourceFilter();
@@ -994,8 +1006,15 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
if (query.getSort() != null) {
for (Sort.Order order : query.getSort()) {
searchRequestBuilder.addSort(order.getProperty(),
order.getDirection() == Sort.Direction.DESC ? SortOrder.DESC : SortOrder.ASC);
FieldSortBuilder sort = SortBuilders.fieldSort(order.getProperty())
.order(order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC);
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
sort.missing("_first");
}
else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) {
sort.missing("_last");
}
searchRequestBuilder.addSort(sort);
}
}
@@ -40,6 +40,8 @@ import org.springframework.data.elasticsearch.core.facet.result.StatisticalResul
import org.springframework.data.elasticsearch.core.facet.result.Term;
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
import static java.util.Optional.ofNullable;
/**
* Container for query result and facet results
*
@@ -48,6 +50,7 @@ import org.springframework.data.elasticsearch.core.facet.result.TermResult;
* @author Artur Konczak
* @author Jonathan Yan
* @author Philipp Kräutli
* @author Remco Zigterman
*/
@Deprecated
public abstract class FacetedPageImpl<T> extends PageImpl<T> implements FacetedPage<T>, AggregatedPage<T> {
@@ -60,7 +63,7 @@ public abstract class FacetedPageImpl<T> extends PageImpl<T> implements FacetedP
}
public FacetedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, Pageable.unpaged(), total);
super(content, ofNullable(pageable).orElse(Pageable.unpaged()), total);
}
@Override
@@ -50,6 +50,8 @@ import static org.springframework.util.StringUtils.*;
* @author Dennis Maaß
* @author Pavel Luhin
* @author Mark Paluch
* @author Sascha Woo
* @author Nordine Bittich
*/
class MappingBuilder {
@@ -67,8 +69,7 @@ class MappingBuilder {
public static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments";
public static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length";
public static final String INDEX_VALUE_NOT_ANALYZED = "not_analyzed";
public static final String TYPE_VALUE_STRING = "text";
public static final String TYPE_VALUE_KEYWORD = "keyword";
public static final String TYPE_VALUE_GEO_POINT = "geo_point";
public static final String TYPE_VALUE_COMPLETION = "completion";
public static final String TYPE_VALUE_GEO_HASH_PREFIX = "geohash_prefix";
@@ -215,89 +216,107 @@ class MappingBuilder {
private static void applyDefaultIdFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field)
throws IOException {
xContentBuilder.startObject(field.getName())
.field(FIELD_TYPE, TYPE_VALUE_STRING)
.field(FIELD_INDEX, INDEX_VALUE_NOT_ANALYZED);
.field(FIELD_TYPE, TYPE_VALUE_KEYWORD)
.field(FIELD_INDEX, true);
xContentBuilder.endObject();
}
/**
* Apply mapping for a single @Field annotation
* Add mapping for @Field annotation
*
* @throws IOException
*/
private static void addSingleFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field,
Field fieldAnnotation, boolean nestedOrObjectField) throws IOException {
xContentBuilder.startObject(field.getName());
if(!nestedOrObjectField) {
xContentBuilder.field(FIELD_STORE, fieldAnnotation.store());
private static void addSingleFieldMapping(XContentBuilder builder, java.lang.reflect.Field field, Field annotation, boolean nestedOrObjectField) throws IOException {
builder.startObject(field.getName());
addFieldMappingParameters(builder, annotation, nestedOrObjectField);
builder.endObject();
}
/**
* Add mapping for @MultiField annotation
*
* @throws IOException
*/
private static void addMultiFieldMapping(
XContentBuilder builder,
java.lang.reflect.Field field,
MultiField annotation,
boolean nestedOrObjectField) throws IOException {
// main field
builder.startObject(field.getName());
addFieldMappingParameters(builder, annotation.mainField(), nestedOrObjectField);
// inner fields
builder.startObject("fields");
for (InnerField innerField : annotation.otherFields()) {
builder.startObject(innerField.suffix());
addFieldMappingParameters(builder, innerField, false);
builder.endObject();
}
if(fieldAnnotation.fielddata()) {
xContentBuilder.field(FIELD_DATA, fieldAnnotation.fielddata());
builder.endObject();
builder.endObject();
}
private static void addFieldMappingParameters(XContentBuilder builder, Object annotation, boolean nestedOrObjectField) throws IOException {
boolean index = true;
boolean store = false;
boolean fielddata = false;
FieldType type = null;
DateFormat dateFormat = null;
String datePattern = null;
String analyzer = null;
String searchAnalyzer = null;
if (annotation instanceof Field) {
// @Field
Field fieldAnnotation = (Field) annotation;
index = fieldAnnotation.index();
store = fieldAnnotation.store();
fielddata = fieldAnnotation.fielddata();
type = fieldAnnotation.type();
dateFormat = fieldAnnotation.format();
datePattern = fieldAnnotation.pattern();
analyzer = fieldAnnotation.analyzer();
searchAnalyzer = fieldAnnotation.searchAnalyzer();
} else if (annotation instanceof InnerField) {
// @InnerField
InnerField fieldAnnotation = (InnerField) annotation;
index = fieldAnnotation.index();
store = fieldAnnotation.store();
fielddata = fieldAnnotation.fielddata();
type = fieldAnnotation.type();
dateFormat = fieldAnnotation.format();
datePattern = fieldAnnotation.pattern();
analyzer = fieldAnnotation.analyzer();
searchAnalyzer = fieldAnnotation.searchAnalyzer();
} else {
throw new IllegalArgumentException("annotation must be an instance of @Field or @InnerField");
}
if (FieldType.Auto != fieldAnnotation.type()) {
xContentBuilder.field(FIELD_TYPE, fieldAnnotation.type().name().toLowerCase());
if (FieldType.Date == fieldAnnotation.type() && DateFormat.none != fieldAnnotation.format()) {
xContentBuilder.field(FIELD_FORMAT, DateFormat.custom == fieldAnnotation.format()
? fieldAnnotation.pattern() : fieldAnnotation.format());
if (!nestedOrObjectField) {
builder.field(FIELD_STORE, store);
}
if (fielddata) {
builder.field(FIELD_DATA, fielddata);
}
if (type != FieldType.Auto) {
builder.field(FIELD_TYPE, type.name().toLowerCase());
if (type == FieldType.Date && dateFormat != DateFormat.none) {
builder.field(FIELD_FORMAT, dateFormat == DateFormat.custom ? datePattern : dateFormat.toString());
}
}
if(!fieldAnnotation.index()) {
xContentBuilder.field(FIELD_INDEX, fieldAnnotation.index());
if (!index) {
builder.field(FIELD_INDEX, index);
}
if (isNotBlank(fieldAnnotation.searchAnalyzer())) {
xContentBuilder.field(FIELD_SEARCH_ANALYZER, fieldAnnotation.searchAnalyzer());
if (isNotBlank(analyzer)) {
builder.field(FIELD_INDEX_ANALYZER, analyzer);
}
if (isNotBlank(fieldAnnotation.analyzer())) {
xContentBuilder.field(FIELD_INDEX_ANALYZER, fieldAnnotation.analyzer());
if (isNotBlank(searchAnalyzer)) {
builder.field(FIELD_SEARCH_ANALYZER, searchAnalyzer);
}
xContentBuilder.endObject();
}
/**
* Apply mapping for a single nested @Field annotation
*
* @throws IOException
*/
private static void addNestedFieldMapping(XContentBuilder builder, java.lang.reflect.Field field,
InnerField annotation) throws IOException {
builder.startObject(annotation.suffix());
//builder.field(FIELD_STORE, annotation.store());
if (FieldType.Auto != annotation.type()) {
builder.field(FIELD_TYPE, annotation.type().name().toLowerCase());
}
if(!annotation.index()) {
builder.field(FIELD_INDEX, annotation.index());
}
if (isNotBlank(annotation.searchAnalyzer())) {
builder.field(FIELD_SEARCH_ANALYZER, annotation.searchAnalyzer());
}
if (isNotBlank(annotation.indexAnalyzer())) {
builder.field(FIELD_INDEX_ANALYZER, annotation.indexAnalyzer());
}
if (annotation.fielddata()) {
builder.field(FIELD_DATA, annotation.fielddata());
}
builder.endObject();
}
/**
* Multi field mappings for string type fields, support for sorts and facets
*
* @throws IOException
*/
private static void addMultiFieldMapping(XContentBuilder builder, java.lang.reflect.Field field,
MultiField annotation, boolean nestedOrObjectField) throws IOException {
builder.startObject(field.getName());
builder.field(FIELD_TYPE, annotation.mainField().type());
builder.startObject("fields");
//add standard field
//addSingleFieldMapping(builder, field, annotation.mainField(), nestedOrObjectField);
for (InnerField innerField : annotation.otherFields()) {
addNestedFieldMapping(builder, field, innerField);
}
builder.endObject();
builder.endObject();
}
protected static boolean isEntity(java.lang.reflect.Field field) {
@@ -55,6 +55,7 @@ import org.springframework.util.Assert;
* @author Kevin Leturc
* @author Mark Paluch
* @author Christoph Strobl
* @author Michael Wirth
*/
public abstract class AbstractElasticsearchRepository<T, ID extends Serializable>
implements ElasticsearchRepository<T, ID> {
@@ -188,7 +189,7 @@ public abstract class AbstractElasticsearchRepository<T, ID extends Serializable
@Override
public boolean existsById(ID id) {
return findById(id) != null;
return findById(id).isPresent();
}
@Override
+48
View File
@@ -1,6 +1,54 @@
Spring Data Elasticsearch Changelog
===================================
Changes in version 3.0.8.RELEASE (2018-06-13)
---------------------------------------------
* DATAES-460 - Avoid pulling in Netty 3 as dependency.
* DATAES-448 - Release 3.0.8 (Kay SR8).
* DATAES-420 - Analyzer of main field ignored when using @MultiField annotation.
* DATAES-312 - NullHandling.NULLS_LAST not working in query.sort.
Changes in version 2.1.13.RELEASE (2018-06-13)
----------------------------------------------
* DATAES-447 - Release 2.1.13 (Ingalls SR13).
Changes in version 3.1.0.M3 (2018-05-17)
----------------------------------------
* DATAES-451 - Adapt to SpEL extension API changes in Spring Data Commons.
* DATAES-440 - Release 3.1 M3 (Lovelace).
* DATAES-422 - Add support for IndicesOptions in search queries.
* DATAES-420 - Analyzer of main field ignored when using @MultiField annotation.
* DATAES-412 - Highlighted fields is not getting passed to the elastic search query.
* DATAES-363 - AbstractElasticsearchRepository.existsById(..) always returns true.
* DATAES-312 - NullHandling.NULLS_LAST not working in query.sort.
* DATAES-198 - @Version has no effect, so therefore is not useful with spring data elasticsearch.
Changes in version 3.0.7.RELEASE (2018-05-08)
---------------------------------------------
* DATAES-438 - Expected a boolean [true/false] for property [index] but got [not_analyzed].
* DATAES-437 - Release 3.0.7 (Kay SR7).
* DATAES-412 - Highlighted fields is not getting passed to the elastic search query.
* DATAES-402 - Paging not working correctly.
* DATAES-363 - AbstractElasticsearchRepository.existsById(..) always returns true.
* DATAES-198 - @Version has no effect, so therefore is not useful with spring data elasticsearch.
Changes in version 2.1.12.RELEASE (2018-05-08)
----------------------------------------------
* DATAES-436 - Release 2.1.12 (Ingalls SR12).
Changes in version 3.1.0.M2 (2018-04-13)
----------------------------------------
* DATAES-439 - Adapt to API changes in Spring Data Commons.
* DATAES-434 - Remove explicit declaration of Jackson library versions.
* DATAES-432 - Export composable repositories via CDI.
* DATAES-427 - Release 3.1 M2 (Lovelace).
Changes in version 3.0.6.RELEASE (2018-04-04)
---------------------------------------------
* DATAES-434 - Remove explicit declaration of Jackson library versions.
+1 -1
View File
@@ -1,4 +1,4 @@
Spring Data Elasticsearch 3.0.6
Spring Data Elasticsearch 3.0.8
Copyright (c) [2013-2016] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -16,14 +16,15 @@
package org.springframework.data.elasticsearch.core;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import com.fasterxml.jackson.databind.util.ArrayIterator;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
@@ -41,6 +42,7 @@ import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.entities.Car;
import org.springframework.data.elasticsearch.entities.SampleEntity;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.*;
@@ -50,6 +52,7 @@ import static org.mockito.Mockito.*;
/**
* @author Artur Konczak
* @author Mohsin Husen
* @author Chris White
* @author Mark Paluch
*/
public class DefaultResultMapperTests {
@@ -153,6 +156,69 @@ public class DefaultResultMapperTests {
assertThat(result.getId(), is("identifier"));
}
@Test // DATAES-198
public void setsVersionFromGetResponse() {
GetResponse response = mock(GetResponse.class);
when(response.getSourceAsString()).thenReturn("{}");
when(response.getVersion()).thenReturn(1234L);
SampleEntity result = resultMapper.mapResult(response, SampleEntity.class);
assertThat(result, is(notNullValue()));
assertThat(result.getVersion(), is(1234L));
}
@Test // DATAES-198
public void setsVersionFromMultiGetResponse() {
GetResponse response1 = mock(GetResponse.class);
when(response1.getSourceAsString()).thenReturn("{}");
when(response1.isExists()).thenReturn(true);
when(response1.getVersion()).thenReturn(1234L);
GetResponse response2 = mock(GetResponse.class);
when(response2.getSourceAsString()).thenReturn("{}");
when(response2.isExists()).thenReturn(true);
when(response2.getVersion()).thenReturn(5678L);
MultiGetResponse multiResponse = mock(MultiGetResponse.class);
when(multiResponse.getResponses()).thenReturn(new MultiGetItemResponse[] {
new MultiGetItemResponse(response1, null), new MultiGetItemResponse(response2, null) });
LinkedList<SampleEntity> results = resultMapper.mapResults(multiResponse, SampleEntity.class);
assertThat(results, is(notNullValue()));
assertThat(results, hasSize(2));
assertThat(results.get(0).getVersion(), is(1234L));
assertThat(results.get(1).getVersion(), is(5678L));
}
@Test // DATAES-198
public void setsVersionFromSearchResponse() {
SearchHit hit1 = mock(SearchHit.class);
when(hit1.getSourceAsString()).thenReturn("{}");
when(hit1.getVersion()).thenReturn(1234L);
SearchHit hit2 = mock(SearchHit.class);
when(hit2.getSourceAsString()).thenReturn("{}");
when(hit2.getVersion()).thenReturn(5678L);
SearchHits searchHits = mock(SearchHits.class);
when(searchHits.getTotalHits()).thenReturn(2L);
when(searchHits.iterator()).thenReturn(Arrays.asList(hit1, hit2).iterator());
SearchResponse searchResponse = mock(SearchResponse.class);
when(searchResponse.getHits()).thenReturn(searchHits);
AggregatedPage<SampleEntity> results = resultMapper.mapResults(searchResponse, SampleEntity.class,
mock(Pageable.class));
assertThat(results, is(notNullValue()));
assertThat(results.getContent().get(0).getVersion(), is(1234L));
assertThat(results.getContent().get(1).getVersion(), is(5678L));
}
private Aggregation createCarAggregation() {
Aggregation aggregation = mock(Terms.class);
when(aggregation.getName()).thenReturn("Diesel");
@@ -33,6 +33,7 @@ import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.hamcrest.Matchers;
@@ -70,6 +71,8 @@ import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
* @author Abdul Mohammed
* @author Kevin Leturc
* @author Mason Chan
* @author Chris White
* @author Sascha Woo
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
@@ -461,6 +464,106 @@ public class ElasticsearchTemplateTests {
assertThat(sampleEntities.getContent().get(1).getMessage(), is(sampleEntity1.getMessage()));
}
@Test // DATAES-312
public void shouldSortResultsGivenNullFirstSortCriteria() {
// given
List<IndexQuery> indexQueries;
// first document
String documentId = randomNumeric(5);
SampleEntity sampleEntity1 = SampleEntity.builder()
.id(documentId)
.message("abc")
.rate(15)
.version(System.currentTimeMillis())
.build();
// second document
String documentId2 = randomNumeric(5);
SampleEntity sampleEntity2 = SampleEntity.builder()
.id(documentId2)
.message("xyz")
.rate(5)
.version(System.currentTimeMillis())
.build();
// third document
String documentId3 = randomNumeric(5);
SampleEntity sampleEntity3 = SampleEntity.builder()
.id(documentId3)
.rate(10)
.version(System.currentTimeMillis())
.build();
indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.refresh(SampleEntity.class);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst())))
.build();
// when
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
// then
assertThat(sampleEntities.getTotalElements(), equalTo(3L));
assertThat(sampleEntities.getContent().get(0).getRate(), is(sampleEntity3.getRate()));
assertThat(sampleEntities.getContent().get(1).getMessage(), is(sampleEntity1.getMessage()));
}
@Test // DATAES-312
public void shouldSortResultsGivenNullLastSortCriteria() {
// given
List<IndexQuery> indexQueries;
// first document
String documentId = randomNumeric(5);
SampleEntity sampleEntity1 = SampleEntity.builder()
.id(documentId)
.message("abc")
.rate(15)
.version(System.currentTimeMillis())
.build();
// second document
String documentId2 = randomNumeric(5);
SampleEntity sampleEntity2 = SampleEntity.builder()
.id(documentId2)
.message("xyz")
.rate(5)
.version(System.currentTimeMillis())
.build();
// third document
String documentId3 = randomNumeric(5);
SampleEntity sampleEntity3 = SampleEntity.builder()
.id(documentId3)
.rate(10)
.version(System.currentTimeMillis())
.build();
indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.refresh(SampleEntity.class);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast())))
.build();
// when
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
// then
assertThat(sampleEntities.getTotalElements(), equalTo(3L));
assertThat(sampleEntities.getContent().get(0).getRate(), is(sampleEntity1.getRate()));
assertThat(sampleEntities.getContent().get(1).getMessage(), is(sampleEntity2.getMessage()));
}
@Test
public void shouldExecuteStringQuery() {
// given
@@ -1206,6 +1309,58 @@ public class ElasticsearchTemplateTests {
assertThat(sampleEntities.getContent().get(0).getHighlightedMessage(), is(highlightedMessage));
}
@Test // DATAES-412
public void shouldReturnMultipleHighlightFields() {
// given
String documentId = randomNumeric(5);
String actualType = "some test type";
String actualMessage = "some test message";
String highlightedType = "some <em>test</em> type";
String highlightedMessage = "some <em>test</em> message";
SampleEntity sampleEntity = SampleEntity.builder()
.id(documentId)
.type(actualType)
.message(actualMessage)
.version(System.currentTimeMillis())
.build();
IndexQuery indexQuery = getIndexQuery(sampleEntity);
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.refresh(SampleEntity.class);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(
boolQuery()
.must(termQuery("type", "test"))
.must(termQuery("message", "test")))
.withHighlightFields(
new HighlightBuilder.Field("type"),
new HighlightBuilder.Field("message"))
.build();
// when
elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
for (SearchHit searchHit : response.getHits()) {
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
HighlightField highlightFieldType = highlightFields.get("type");
HighlightField highlightFieldMessage = highlightFields.get("message");
// then
assertNotNull(highlightFieldType);
assertNotNull(highlightFieldMessage);
assertThat(highlightFieldType.fragments()[0].toString(), is(highlightedType));
assertThat(highlightFieldMessage.fragments()[0].toString(), is(highlightedMessage));
}
return null;
}
});
}
@Test
public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() {
// given
@@ -1987,13 +2142,17 @@ public class ElasticsearchTemplateTests {
}
private IndexQuery getIndexQuery(SampleEntity sampleEntity) {
return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build();
return new IndexQueryBuilder()
.withId(sampleEntity.getId())
.withObject(sampleEntity)
.withVersion(sampleEntity.getVersion())
.build();
}
private List<IndexQuery> getIndexQueries(List<SampleEntity> sampleEntities) {
List<IndexQuery> indexQueries = new ArrayList<>();
for (SampleEntity sampleEntity : sampleEntities) {
indexQueries.add(new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build());
indexQueries.add(getIndexQuery(sampleEntity));
}
return indexQueries;
}
@@ -2011,4 +2170,4 @@ public class ElasticsearchTemplateTests {
this.lastName = lastName;
}
}
}
}
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.junit.Test;
@@ -43,6 +44,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Jakub Vavrik
* @author Mohsin Husen
* @author Keivn Leturc
* @author Nordine Bittich
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
@@ -189,8 +191,28 @@ public class MappingBuilderTests {
elasticsearchTemplate.createIndex(Book.class);
elasticsearchTemplate.putMapping(Book.class);
//when
//then
}
@Test // DATAES-420
public void shouldUseBothAnalyzer() {
//given
elasticsearchTemplate.deleteIndex(Book.class);
elasticsearchTemplate.createIndex(Book.class);
elasticsearchTemplate.putMapping(Book.class);
//when
Map mapping = elasticsearchTemplate.getMapping(Book.class);
Map descriptionMapping = (Map) ((Map) mapping.get("properties")).get("description");
Map prefixDescription = (Map) ((Map) descriptionMapping.get("fields")).get("prefix");
//then
assertThat(prefixDescription.size(), is(3));
assertThat(prefixDescription.get("type"), equalTo("text"));
assertThat(prefixDescription.get("analyzer"), equalTo("stop"));
assertThat(prefixDescription.get("search_analyzer"), equalTo("standard"));
assertThat(descriptionMapping.get("type"), equalTo("text"));
assertThat(descriptionMapping.get("analyzer"), equalTo("whitespace"));
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.aggregation;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import java.util.Arrays;
/**
* @author Remco Zigterman
*/
public class AggregatedPageImplTest {
@Test
public void constructFacetedPageWithPageable() {
Page<String> page = new AggregatedPageImpl<>(Arrays.asList("Test", "Test 2"), PageRequest.of(0, 2), 10);
assertEquals(10, page.getTotalElements());
assertEquals(2, page.getNumberOfElements());
assertEquals(2, page.getSize());
assertEquals(5, page.getTotalPages());
}
}
@@ -16,7 +16,7 @@
package org.springframework.data.elasticsearch.core.facet;
import static org.springframework.data.elasticsearch.annotations.FieldType.Integer;
import static org.springframework.data.elasticsearch.annotations.FieldType.text;
import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
import java.util.ArrayList;
import java.util.List;
@@ -36,14 +36,14 @@ public class ArticleEntity {
@Id
private String id;
private String title;
@Field(type = text, fielddata = true)
@Field(type = Text, fielddata = true)
private String subject;
@MultiField(
mainField = @Field(type = text),
mainField = @Field(type = Text),
otherFields = {
@InnerField(suffix = "untouched", type = text, store = true, fielddata = true, indexAnalyzer = "keyword"),
@InnerField(suffix = "sort", type = text, store = true, indexAnalyzer = "keyword")
@InnerField(suffix = "untouched", type = Text, store = true, fielddata = true, analyzer = "keyword"),
@InnerField(suffix = "sort", type = Text, store = true, analyzer = "keyword")
}
)
private List<String> authors = new ArrayList<>();
@@ -29,10 +29,13 @@ 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 org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Nordine Bittich
*/
@Setter
@Getter
@@ -49,4 +52,11 @@ public class Book {
private Author author;
@Field(type = FieldType.Nested)
private Map<Integer, Collection<String>> buckets = new HashMap<>();
@MultiField(
mainField = @Field(type = FieldType.Text, analyzer = "whitespace"),
otherFields = {
@InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard")
}
)
private String description;
}
@@ -19,7 +19,6 @@ import org.springframework.core.style.ToStringCreator;
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.FieldIndex;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Parent;
@@ -38,7 +37,7 @@ public class ParentEntity {
@Id
private String id;
@Field(type = FieldType.text, store = true)
@Field(type = FieldType.Text, store = true)
private String name;
public ParentEntity() {
@@ -67,10 +66,10 @@ public class ParentEntity {
@Id
private String id;
@Field(type = FieldType.text, store = true)
@Field(type = FieldType.Text, store = true)
@Parent(type = PARENT_TYPE)
private String parentId;
@Field(type = FieldType.text, store = true)
@Field(type = FieldType.Text, store = true)
private String name;
public ChildEntity() {
@@ -1,7 +1,7 @@
package org.springframework.data.elasticsearch.entities;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.text;
import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
import java.util.Date;
@@ -19,7 +19,7 @@ public class SampleDateMappingEntity {
@Id
private String id;
@Field(type = text, index = false, store = true, analyzer = "standard")
@Field(type = Text, index = false, store = true, analyzer = "standard")
private String message;
@Field(type = Date, format = DateFormat.custom, pattern = "dd.MM.yyyy hh:mm")
@@ -23,6 +23,7 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.elasticsearch.annotations.Document;
@@ -34,21 +35,23 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Chris White
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@Document(indexName = "test-index-sample", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1")
public class SampleEntity {
@Id
private String id;
@Field(type = text, store = true, fielddata = true)
@Field(type = Text, store = true, fielddata = true)
private String type;
@Field(type = text, store = true, fielddata = true)
@Field(type = Text, store = true, fielddata = true)
private String message;
private int rate;
@ScriptedField
@@ -48,7 +48,7 @@ public class SampleEntityUUIDKeyed {
@Id
private UUID id;
private String type;
@Field(type = FieldType.text, fielddata = true)
@Field(type = FieldType.Text, fielddata = true)
private String message;
private int rate;
@ScriptedField
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.entities;
import static org.springframework.data.elasticsearch.annotations.FieldType.text;
import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
@@ -26,7 +26,7 @@ import org.springframework.data.elasticsearch.annotations.Field;
@Document(indexName = "test-index-sample-inherited", type = "mapping", shards = 1, replicas = 0, refreshInterval = "-1")
public class SampleInheritedEntity extends AbstractInheritedEntity {
@Field(type = text, index = false, store = true, analyzer = "standard")
@Field(type = Text, index = false, store = true, analyzer = "standard")
private String message;
public String getMessage() {
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.entities;
import static org.springframework.data.elasticsearch.annotations.FieldType.text;
import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@@ -31,7 +31,7 @@ public class SampleMappingEntity {
@Id
private String id;
@Field(type = text, index = false, store = true, analyzer = "standard")
@Field(type = Text, index = false, store = true, analyzer = "standard")
private String message;
private NestedEntity nested;
@@ -54,7 +54,7 @@ public class SampleMappingEntity {
static class NestedEntity {
@Field(type = text)
@Field(type = Text)
private String someField;
public String getSomeField() {
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.entities;
import static org.springframework.data.elasticsearch.annotations.FieldType.text;
import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
@@ -31,7 +31,7 @@ public class SampleTransientEntity {
@Id
private String id;
@Field(type = text, index = false, store = true, analyzer = "standard")
@Field(type = Text, index = false, store = true, analyzer = "standard")
private String message;
@Transient
@@ -47,6 +47,7 @@ import static org.springframework.data.domain.Sort.Direction.*;
* @author Mohsin Husen
* @author Mark Paluch
* @author Christoph Strobl
* @author Michael Wirth
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/simple-repository-test.xml")
@@ -274,6 +275,19 @@ public class SimpleElasticsearchRepositoryTests {
assertEquals(exist, true);
}
@Test // DATAES-363
public void shouldReturnFalseGivenDocumentWithIdDoesNotExist() {
// given
String documentId = randomNumeric(5);
// when
boolean exist = repository.existsById(documentId);
// then
assertThat(exist, is(false));
}
@Test
public void shouldReturnResultsForGivenSearchQuery() {
// given
@@ -45,6 +45,7 @@ import static org.junit.Assert.*;
* @author Mohsin Husen
* @author Mark Paluch
* @author Christoph Strobl
* @author Michael Wirth
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/simple-repository-test.xml")
@@ -262,6 +263,19 @@ public class UUIDElasticsearchRepositoryTests {
assertEquals(exist, true);
}
@Test // DATAES-363
public void shouldReturnFalseGivenDocumentWithIdDoesNotExist() {
// given
UUID documentId = UUID.randomUUID();
// when
boolean exist = repository.existsById(documentId);
// then
assertThat(exist, is(false));
}
@Test
public void shouldDeleteAll() {
// when