1
0
mirror of synced 2026-07-06 02:00:19 +00:00

Compare commits

...

67 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
Mark Paluch be230f4003 DATAES-430 - Release version 3.0.6 (Kay SR6). 2018-04-04 15:53:23 +02:00
Mark Paluch 8c1821e7a6 DATAES-430 - Prepare 3.0.6 (Kay SR6). 2018-04-04 15:52:32 +02:00
Mark Paluch 72a2f9f758 DATAES-430 - Updated changelog. 2018-04-04 15:52:30 +02:00
Mark Paluch d9d3521518 DATAES-423 - Updated changelog. 2018-04-04 15:16:23 +02:00
Oliver Gierke d50ae96c5e DATAES-434 - Removed explicit declaration of Jackson library versions. 2018-03-27 19:38:04 +02:00
Mark Paluch 734a28fb03 DATAES-429 - After release cleanups. 2018-02-28 10:43:36 +01:00
Mark Paluch ac403b9198 DATAES-429 - Prepare next development iteration. 2018-02-28 10:43:34 +01:00
Mark Paluch 477c4d1dc3 DATAES-429 - Release version 3.0.5 (Kay SR5). 2018-02-28 10:14:58 +01:00
Mark Paluch 2b543ff026 DATAES-429 - Prepare 3.0.5 (Kay SR5). 2018-02-28 10:14:06 +01:00
Mark Paluch 02a3e120c2 DATAES-429 - Updated changelog. 2018-02-28 10:14:04 +01:00
Mark Paluch 92286a725d DATAES-425 - After release cleanups. 2018-02-19 20:29:08 +01:00
Mark Paluch 462288be0e DATAES-425 - Prepare next development iteration. 2018-02-19 20:29:07 +01:00
Mark Paluch b844f47795 DATAES-425 - Release version 3.0.4 (Kay SR4). 2018-02-19 19:46:54 +01:00
Mark Paluch fe488eac32 DATAES-425 - Prepare 3.0.4 (Kay SR4). 2018-02-19 19:46:05 +01:00
Mark Paluch a77b81ecb3 DATAES-425 - Updated changelog. 2018-02-19 19:46:03 +01:00
Christoph Strobl 81795f67cd DATAES-401 - Updated changelog. 2018-02-06 11:14:01 +01:00
Mark Paluch 485859ca3d DATAES-417 - After release cleanups. 2018-01-24 13:46:10 +01:00
Mark Paluch 8973d2d7eb DATAES-417 - Prepare next development iteration. 2018-01-24 13:46:09 +01:00
Mark Paluch a525a38825 DATAES-417 - Release version 3.0.3 (Kay SR3). 2018-01-24 13:21:24 +01:00
Mark Paluch b392090e61 DATAES-417 - Prepare 3.0.3 (Kay SR3). 2018-01-24 13:20:39 +01:00
Mark Paluch ca4a864f9e DATAES-417 - Updated changelog. 2018-01-24 13:20:38 +01:00
Mark Paluch 3a31030f89 DATAES-424 - Fix line endings to LF. 2018-01-24 13:09:22 +01:00
Mark Paluch 34a7900e34 DATAES-416 - Updated changelog. 2018-01-24 12:22:15 +01:00
Mark Paluch 361bc2a333 DATAES-411 - After release cleanups. 2017-11-27 16:42:55 +01:00
Mark Paluch c2c21581d8 DATAES-411 - Prepare next development iteration. 2017-11-27 16:42:53 +01:00
Mark Paluch ecf2efa6e5 DATAES-411 - Release version 3.0.2 (Kay SR2). 2017-11-27 16:12:35 +01:00
Mark Paluch 418d259fbf DATAES-411 - Prepare 3.0.2 (Kay SR2). 2017-11-27 16:11:22 +01:00
Mark Paluch 737a023b5a DATAES-411 - Updated changelog. 2017-11-27 16:11:20 +01:00
Mark Paluch cc3f578312 DATAES-404 - Updated changelog. 2017-11-27 15:58:48 +01:00
Oliver Gierke 81b21f4e6f DATAES-414 - Reduced scope of Log4j dependencies to test. 2017-11-02 18:42:30 +01:00
Oliver Gierke 552cbff6a4 DATAES-400 - After release cleanups. 2017-10-27 15:50:49 +02:00
Oliver Gierke 000eb152dc DATAES-400 - Prepare next development iteration. 2017-10-27 15:50:47 +02:00
Oliver Gierke ad55402973 DATAES-400 - Release version 3.0.1 (Kay SR1). 2017-10-27 15:25:13 +02:00
Oliver Gierke ef68623d5b DATAES-400 - Prepare 3.0.1 (Kay SR1). 2017-10-27 15:24:26 +02:00
Oliver Gierke c075f170c3 DATAES-400 - Updated changelog. 2017-10-27 15:24:22 +02:00
Oliver Gierke 02b7dde196 DATAES-410 - Adapt API changes in Property in test cases. 2017-10-27 11:24:54 +02:00
Vladimir Tsanev 51b7fa2a26 DATAES-361 - Move Log4j2 config file to test sources.
The configuration file for Log4j2 had been added to src/main/resources accidentally which caused it to be picked up by user applications, e.g. in a Spring Boot application effectively disabling Boot's auto-configuration. This file has now been moved to the test resources.

Original pull request: #191.
Related tickets: spring-projects/spring-boot#10634
2017-10-13 15:41:11 +02:00
Oliver Gierke 4e5051c57b DATAES-391 - Updated changelog. 2017-10-11 19:03:34 +02:00
Mark Paluch 31d499e6e0 DATAES-392 - After release cleanups. 2017-10-02 11:38:05 +02:00
Mark Paluch 311a06aa67 DATAES-392 - Prepare next development iteration. 2017-10-02 11:38:04 +02:00
103 changed files with 12101 additions and 11497 deletions
+6 -11
View File
@@ -52,17 +52,12 @@ the appropriate dependency version.
</repository> </repository>
``` ```
| spring data elasticsearch | elasticsearch | | spring data elasticsearch | elasticsearch |
|:-----------------------------------:|:-------------:| |:-------------------------:|:-------------:|
| 3.0.0.RC2 | 5.5.0 | | 3.0.x | 5.5.0 |
| 3.0.0.M4 | 5.4.0 | | 2.1.x | 2.4.0 |
| 2.0.4.RELEASE | 2.4.0 | | 2.0.x | 2.2.0 |
| 2.0.0.RELEASE | 2.2.0 | | 1.3.x | 1.5.2 |
| 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 |
### ElasticsearchRepository ### ElasticsearchRepository
+18 -17
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId> <artifactId>spring-data-elasticsearch</artifactId>
<version>3.0.0.RELEASE</version> <version>3.0.8.RELEASE</version>
<parent> <parent>
<groupId>org.springframework.data.build</groupId> <groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId> <artifactId>spring-data-parent</artifactId>
<version>2.0.0.RELEASE</version> <version>2.0.8.RELEASE</version>
</parent> </parent>
<name>Spring Data Elasticsearch</name> <name>Spring Data Elasticsearch</name>
@@ -20,7 +20,8 @@
<commonscollections>3.2.1</commonscollections> <commonscollections>3.2.1</commonscollections>
<commonslang>2.6</commonslang> <commonslang>2.6</commonslang>
<elasticsearch>5.5.0</elasticsearch> <elasticsearch>5.5.0</elasticsearch>
<springdata.commons>2.0.0.RELEASE</springdata.commons> <log4j>2.8.2</log4j>
<springdata.commons>2.0.8.RELEASE</springdata.commons>
<java-module-name>spring.data.elasticsearch</java-module-name> <java-module-name>spring.data.elasticsearch</java-module-name>
</properties> </properties>
@@ -80,31 +81,41 @@
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</exclusion> </exclusion>
<exclusion>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty3-client</artifactId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version>
</dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId> <artifactId>log4j-over-slf4j</artifactId>
<version>1.7.22</version> <version>${slf4j}</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.8.2</version> <version>${log4j}</version>
<scope>test</scope>
</dependency> </dependency>
<!-- Jackson JSON Mapper --> <!-- Jackson JSON Mapper -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId> <artifactId>jackson-core</artifactId>
<version>${jackson}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson}</version>
</dependency> </dependency>
<!-- CDI --> <!-- CDI -->
@@ -161,14 +172,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<!-- required by elasticsearch -->
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
@@ -176,8 +179,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
@@ -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 * @author Artur Konczak
*/ */
public enum FieldType { 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; boolean index() default true;
DateFormat format() default DateFormat.none;
String pattern() default "";
boolean store() default false; boolean store() default false;
boolean fielddata() default false; boolean fielddata() default false;
String searchAnalyzer() default ""; 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 static org.apache.commons.lang.StringUtils.*;
import io.netty.util.ThreadDeathWatcher;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.net.InetAddress; 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.Properties;
import java.util.concurrent.TimeUnit;
import org.elasticsearch.client.transport.TransportClient; 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.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress; 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.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.FactoryBean;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/** /**
* TransportClientFactoryBean * TransportClientFactoryBean
@@ -88,7 +106,7 @@ public class TransportClientFactoryBean implements FactoryBean<TransportClient>,
protected void buildClient() throws Exception { protected void buildClient() throws Exception {
client = new PreBuiltTransportClient(settings()); client = new SpringDataTransportClient(settings());
Assert.hasText(clusterNodes, "[Assertion failed] clusterNodes settings missing."); Assert.hasText(clusterNodes, "[Assertion failed] clusterNodes settings missing.");
for (String clusterNode : split(clusterNodes, COMMA)) { for (String clusterNode : split(clusterNodes, COMMA)) {
String hostName = substringBeforeLast(clusterNode, COLON); String hostName = substringBeforeLast(clusterNode, COLON);
@@ -153,4 +171,97 @@ public class TransportClientFactoryBean implements FactoryBean<TransportClient>,
public void setProperties(Properties properties) { public void setProperties(Properties properties) {
this.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.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonFactory;
@@ -49,6 +50,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
* @author Petar Tahchiev * @author Petar Tahchiev
* @author Young Gu * @author Young Gu
* @author Oliver Gierke * @author Oliver Gierke
* @author Chris White
* @author Mark Paluch * @author Mark Paluch
*/ */
public class DefaultResultMapper extends AbstractResultMapper { public class DefaultResultMapper extends AbstractResultMapper {
@@ -88,6 +90,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
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);
populateScriptFields(result, hit); populateScriptFields(result, hit);
results.add(result); results.add(result);
} }
@@ -153,6 +156,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
T result = mapEntity(response.getSourceAsString(), clazz); T result = mapEntity(response.getSourceAsString(), clazz);
if (result != null) { if (result != null) {
setPersistentEntityId(result, response.getId(), clazz); setPersistentEntityId(result, response.getId(), clazz);
setPersistentEntityVersion(result, response.getVersion(), clazz);
} }
return result; return result;
} }
@@ -164,6 +168,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
if (!response.isFailed() && response.getResponse().isExists()) { if (!response.isFailed() && response.getResponse().isExists()) {
T result = mapEntity(response.getResponse().getSourceAsString(), clazz); T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
setPersistentEntityId(result, response.getResponse().getId(), clazz); setPersistentEntityId(result, response.getResponse().getId(), clazz);
setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz);
list.add(result); 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.SearchHit;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; 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.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.SuggestBuilder; import org.elasticsearch.search.suggest.SuggestBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -105,7 +107,10 @@ import static org.springframework.util.CollectionUtils.isEmpty;
* @author Young Gu * @author Young Gu
* @author Oliver Gierke * @author Oliver Gierke
* @author Mark Janssen * @author Mark Janssen
* @author Chris White
* @author Mark Paluch * @author Mark Paluch
* @author Sascha Woo
* @author Ted Liang
*/ */
public class ElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { public class ElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware {
@@ -730,7 +735,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) { private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) {
SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices())) 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()){ if(query.getPageable().isPaged()){
requestBuilder.setSize(query.getPageable().getPageSize()); requestBuilder.setSize(query.getPageable().getPageSize());
@@ -875,9 +883,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
} }
if (searchQuery.getHighlightFields() != null) { if (searchQuery.getHighlightFields() != null) {
HighlightBuilder highlightBuilder = new HighlightBuilder();
for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) {
searchRequest.highlighter(new HighlightBuilder().field(highlightField)); highlightBuilder.field(highlightField);
} }
searchRequest.highlighter(highlightBuilder);
} }
if (!isEmpty(searchQuery.getIndicesBoost())) { if (!isEmpty(searchQuery.getIndicesBoost())) {
@@ -975,7 +985,9 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
int startRecord = 0; int startRecord = 0;
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(toArray(query.getIndices())) 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) { if (query.getSourceFilter() != null) {
SourceFilter sourceFilter = query.getSourceFilter(); SourceFilter sourceFilter = query.getSourceFilter();
@@ -994,8 +1006,15 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
if (query.getSort() != null) { if (query.getSort() != null) {
for (Sort.Order order : query.getSort()) { for (Sort.Order order : query.getSort()) {
searchRequestBuilder.addSort(order.getProperty(), FieldSortBuilder sort = SortBuilders.fieldSort(order.getProperty())
order.getDirection() == Sort.Direction.DESC ? SortOrder.DESC : SortOrder.ASC); .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.Term;
import org.springframework.data.elasticsearch.core.facet.result.TermResult; import org.springframework.data.elasticsearch.core.facet.result.TermResult;
import static java.util.Optional.ofNullable;
/** /**
* Container for query result and facet results * Container for query result and facet results
* *
@@ -48,6 +50,7 @@ import org.springframework.data.elasticsearch.core.facet.result.TermResult;
* @author Artur Konczak * @author Artur Konczak
* @author Jonathan Yan * @author Jonathan Yan
* @author Philipp Kräutli * @author Philipp Kräutli
* @author Remco Zigterman
*/ */
@Deprecated @Deprecated
public abstract class FacetedPageImpl<T> extends PageImpl<T> implements FacetedPage<T>, AggregatedPage<T> { 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) { public FacetedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, Pageable.unpaged(), total); super(content, ofNullable(pageable).orElse(Pageable.unpaged()), total);
} }
@Override @Override
@@ -50,6 +50,8 @@ import static org.springframework.util.StringUtils.*;
* @author Dennis Maaß * @author Dennis Maaß
* @author Pavel Luhin * @author Pavel Luhin
* @author Mark Paluch * @author Mark Paluch
* @author Sascha Woo
* @author Nordine Bittich
*/ */
class MappingBuilder { class MappingBuilder {
@@ -67,8 +69,7 @@ class MappingBuilder {
public static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments"; 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 COMPLETION_MAX_INPUT_LENGTH = "max_input_length";
public static final String INDEX_VALUE_NOT_ANALYZED = "not_analyzed"; public static final String TYPE_VALUE_KEYWORD = "keyword";
public static final String TYPE_VALUE_STRING = "text";
public static final String TYPE_VALUE_GEO_POINT = "geo_point"; public static final String TYPE_VALUE_GEO_POINT = "geo_point";
public static final String TYPE_VALUE_COMPLETION = "completion"; public static final String TYPE_VALUE_COMPLETION = "completion";
public static final String TYPE_VALUE_GEO_HASH_PREFIX = "geohash_prefix"; 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) private static void applyDefaultIdFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field)
throws IOException { throws IOException {
xContentBuilder.startObject(field.getName()) xContentBuilder.startObject(field.getName())
.field(FIELD_TYPE, TYPE_VALUE_STRING) .field(FIELD_TYPE, TYPE_VALUE_KEYWORD)
.field(FIELD_INDEX, INDEX_VALUE_NOT_ANALYZED); .field(FIELD_INDEX, true);
xContentBuilder.endObject(); xContentBuilder.endObject();
} }
/** /**
* Apply mapping for a single @Field annotation * Add mapping for @Field annotation
* *
* @throws IOException * @throws IOException
*/ */
private static void addSingleFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field, private static void addSingleFieldMapping(XContentBuilder builder, java.lang.reflect.Field field, Field annotation, boolean nestedOrObjectField) throws IOException {
Field fieldAnnotation, boolean nestedOrObjectField) throws IOException { builder.startObject(field.getName());
xContentBuilder.startObject(field.getName()); addFieldMappingParameters(builder, annotation, nestedOrObjectField);
if(!nestedOrObjectField) { builder.endObject();
xContentBuilder.field(FIELD_STORE, fieldAnnotation.store()); }
/**
* 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()) { builder.endObject();
xContentBuilder.field(FIELD_DATA, fieldAnnotation.fielddata());
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()) { if (!nestedOrObjectField) {
xContentBuilder.field(FIELD_TYPE, fieldAnnotation.type().name().toLowerCase()); builder.field(FIELD_STORE, store);
if (FieldType.Date == fieldAnnotation.type() && DateFormat.none != fieldAnnotation.format()) { }
xContentBuilder.field(FIELD_FORMAT, DateFormat.custom == fieldAnnotation.format() if (fielddata) {
? fieldAnnotation.pattern() : fieldAnnotation.format()); 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()) { if (!index) {
xContentBuilder.field(FIELD_INDEX, fieldAnnotation.index()); builder.field(FIELD_INDEX, index);
} }
if (isNotBlank(fieldAnnotation.searchAnalyzer())) { if (isNotBlank(analyzer)) {
xContentBuilder.field(FIELD_SEARCH_ANALYZER, fieldAnnotation.searchAnalyzer()); builder.field(FIELD_INDEX_ANALYZER, analyzer);
} }
if (isNotBlank(fieldAnnotation.analyzer())) { if (isNotBlank(searchAnalyzer)) {
xContentBuilder.field(FIELD_INDEX_ANALYZER, fieldAnnotation.analyzer()); 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) { protected static boolean isEntity(java.lang.reflect.Field field) {
@@ -55,6 +55,7 @@ import org.springframework.util.Assert;
* @author Kevin Leturc * @author Kevin Leturc
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Michael Wirth
*/ */
public abstract class AbstractElasticsearchRepository<T, ID extends Serializable> public abstract class AbstractElasticsearchRepository<T, ID extends Serializable>
implements ElasticsearchRepository<T, ID> { implements ElasticsearchRepository<T, ID> {
@@ -188,7 +189,7 @@ public abstract class AbstractElasticsearchRepository<T, ID extends Serializable
@Override @Override
public boolean existsById(ID id) { public boolean existsById(ID id) {
return findById(id) != null; return findById(id).isPresent();
} }
@Override @Override
+115
View File
@@ -1,6 +1,121 @@
Spring Data Elasticsearch Changelog 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.
* DATAES-430 - Release 3.0.6 (Kay SR6).
Changes in version 2.1.11.RELEASE (2018-04-04)
----------------------------------------------
* DATAES-434 - Remove explicit declaration of Jackson library versions.
* DATAES-424 - Fix line endings.
* DATAES-423 - Release 2.1.11 (Ingalls SR11).
Changes in version 3.0.5.RELEASE (2018-02-28)
---------------------------------------------
* DATAES-429 - Release 3.0.5 (Kay SR5).
Changes in version 3.0.4.RELEASE (2018-02-19)
---------------------------------------------
* DATAES-425 - Release 3.0.4 (Kay SR4).
Changes in version 3.1.0.M1 (2018-02-06)
----------------------------------------
* DATAES-424 - Fix line endings.
* DATAES-414 - Reduce scope of Lo4j dependencies to test.
* DATAES-410 - Adapt API changes in Property in test cases.
* DATAES-401 - Release 3.1 M1 (Lovelace).
* DATAES-361 - log4j2.xml in classpath root of the library prevents Spring Boot's logging auto-configuration to work.
Changes in version 3.0.3.RELEASE (2018-01-24)
---------------------------------------------
* DATAES-424 - Fix line endings.
* DATAES-417 - Release 3.0.3 (Kay SR3).
Changes in version 2.1.10.RELEASE (2018-01-24)
----------------------------------------------
* DATAES-416 - Release 2.1.10 (Ingalls SR10).
Changes in version 3.0.2.RELEASE (2017-11-27)
---------------------------------------------
* DATAES-414 - Reduce scope of Lo4j dependencies to test.
* DATAES-411 - Release 3.0.2 (Kay SR2).
Changes in version 2.1.9.RELEASE (2017-11-27)
---------------------------------------------
* DATAES-408 - Ensure Spring 5 compatibility in Ingalls.
* DATAES-404 - Release 2.1.9 (Ingalls SR9).
Changes in version 3.0.1.RELEASE (2017-10-27)
---------------------------------------------
* DATAES-410 - Adapt API changes in Property in test cases.
* DATAES-400 - Release 3.0.1 (Kay SR1).
* DATAES-361 - log4j2.xml in classpath root of the library prevents Spring Boot's logging auto-configuration to work.
Changes in version 2.1.8.RELEASE (2017-10-11)
---------------------------------------------
* DATAES-391 - Release 2.1.8 (Ingalls SR8).
Changes in version 3.0.0.RELEASE (2017-10-02) Changes in version 3.0.0.RELEASE (2017-10-02)
--------------------------------------------- ---------------------------------------------
* DATAES-397 - Add explicit automatic module name for Java 9. * DATAES-397 - Add explicit automatic module name for Java 9.
+1 -1
View File
@@ -1,4 +1,4 @@
Spring Data Elasticsearch 3.0 GA Spring Data Elasticsearch 3.0.8
Copyright (c) [2013-2016] Pivotal Software, Inc. Copyright (c) [2013-2016] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License"). 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; package org.springframework.data.elasticsearch.core;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.databind.util.ArrayIterator; import com.fasterxml.jackson.databind.util.ArrayIterator;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.elasticsearch.action.get.GetResponse; 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.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField; 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.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.entities.Car; import org.springframework.data.elasticsearch.entities.Car;
import org.springframework.data.elasticsearch.entities.SampleEntity;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
@@ -50,6 +52,7 @@ import static org.mockito.Mockito.*;
/** /**
* @author Artur Konczak * @author Artur Konczak
* @author Mohsin Husen * @author Mohsin Husen
* @author Chris White
* @author Mark Paluch * @author Mark Paluch
*/ */
public class DefaultResultMapperTests { public class DefaultResultMapperTests {
@@ -153,6 +156,69 @@ public class DefaultResultMapperTests {
assertThat(result.getId(), is("identifier")); 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() { private Aggregation createCarAggregation() {
Aggregation aggregation = mock(Terms.class); Aggregation aggregation = mock(Terms.class);
when(aggregation.getName()).thenReturn("Diesel"); when(aggregation.getName()).thenReturn("Diesel");
@@ -33,6 +33,7 @@ import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType; import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchHit; 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.sort.FieldSortBuilder; import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.sort.SortOrder;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
@@ -70,6 +71,8 @@ import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
* @author Abdul Mohammed * @author Abdul Mohammed
* @author Kevin Leturc * @author Kevin Leturc
* @author Mason Chan * @author Mason Chan
* @author Chris White
* @author Sascha Woo
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml") @ContextConfiguration("classpath:elasticsearch-template-test.xml")
@@ -461,6 +464,106 @@ public class ElasticsearchTemplateTests {
assertThat(sampleEntities.getContent().get(1).getMessage(), is(sampleEntity1.getMessage())); 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 @Test
public void shouldExecuteStringQuery() { public void shouldExecuteStringQuery() {
// given // given
@@ -1206,6 +1309,58 @@ public class ElasticsearchTemplateTests {
assertThat(sampleEntities.getContent().get(0).getHighlightedMessage(), is(highlightedMessage)); 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 @Test
public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() {
// given // given
@@ -1987,13 +2142,17 @@ public class ElasticsearchTemplateTests {
} }
private IndexQuery getIndexQuery(SampleEntity sampleEntity) { 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) { private List<IndexQuery> getIndexQueries(List<SampleEntity> sampleEntities) {
List<IndexQuery> indexQueries = new ArrayList<>(); List<IndexQuery> indexQueries = new ArrayList<>();
for (SampleEntity sampleEntity : sampleEntities) { for (SampleEntity sampleEntity : sampleEntities) {
indexQueries.add(new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build()); indexQueries.add(getIndexQuery(sampleEntity));
} }
return indexQueries; return indexQueries;
} }
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.junit.Test; import org.junit.Test;
@@ -43,6 +44,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Jakub Vavrik * @author Jakub Vavrik
* @author Mohsin Husen * @author Mohsin Husen
* @author Keivn Leturc * @author Keivn Leturc
* @author Nordine Bittich
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml") @ContextConfiguration("classpath:elasticsearch-template-test.xml")
@@ -189,8 +191,28 @@ public class MappingBuilderTests {
elasticsearchTemplate.createIndex(Book.class); elasticsearchTemplate.createIndex(Book.class);
elasticsearchTemplate.putMapping(Book.class); elasticsearchTemplate.putMapping(Book.class);
//when //when
//then //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; package org.springframework.data.elasticsearch.core.facet;
import static org.springframework.data.elasticsearch.annotations.FieldType.Integer; 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.ArrayList;
import java.util.List; import java.util.List;
@@ -36,14 +36,14 @@ public class ArticleEntity {
@Id @Id
private String id; private String id;
private String title; private String title;
@Field(type = text, fielddata = true) @Field(type = Text, fielddata = true)
private String subject; private String subject;
@MultiField( @MultiField(
mainField = @Field(type = text), mainField = @Field(type = Text),
otherFields = { otherFields = {
@InnerField(suffix = "untouched", type = text, store = true, fielddata = true, indexAnalyzer = "keyword"), @InnerField(suffix = "untouched", type = Text, store = true, fielddata = true, analyzer = "keyword"),
@InnerField(suffix = "sort", type = text, store = true, indexAnalyzer = "keyword") @InnerField(suffix = "sort", type = Text, store = true, analyzer = "keyword")
} }
) )
private List<String> authors = new ArrayList<>(); private List<String> authors = new ArrayList<>();
@@ -66,7 +66,8 @@ public class SimpleElasticsearchPersistentEntityTests {
private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasticsearchPersistentEntity<?> entity, private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasticsearchPersistentEntity<?> entity,
String field) { String field) {
Property property = Property.of(ReflectionUtils.findField(entity.getTypeInformation().getType(), field)); TypeInformation<?> type = entity.getTypeInformation();
Property property = Property.of(type, ReflectionUtils.findField(entity.getType(), field));
return new SimpleElasticsearchPersistentProperty(property, entity, SimpleTypeHolder.DEFAULT); return new SimpleElasticsearchPersistentProperty(property, entity, SimpleTypeHolder.DEFAULT);
} }
@@ -29,10 +29,13 @@ import org.springframework.data.annotation.Id;
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.FieldType; 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 Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Nordine Bittich
*/ */
@Setter @Setter
@Getter @Getter
@@ -49,4 +52,11 @@ public class Book {
private Author author; private Author author;
@Field(type = FieldType.Nested) @Field(type = FieldType.Nested)
private Map<Integer, Collection<String>> buckets = new HashMap<>(); 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.annotation.Id;
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.FieldIndex;
import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Parent;
@@ -38,7 +37,7 @@ public class ParentEntity {
@Id @Id
private String id; private String id;
@Field(type = FieldType.text, store = true) @Field(type = FieldType.Text, store = true)
private String name; private String name;
public ParentEntity() { public ParentEntity() {
@@ -67,10 +66,10 @@ public class ParentEntity {
@Id @Id
private String id; private String id;
@Field(type = FieldType.text, store = true) @Field(type = FieldType.Text, store = true)
@Parent(type = PARENT_TYPE) @Parent(type = PARENT_TYPE)
private String parentId; private String parentId;
@Field(type = FieldType.text, store = true) @Field(type = FieldType.Text, store = true)
private String name; private String name;
public ChildEntity() { public ChildEntity() {
@@ -1,7 +1,7 @@
package org.springframework.data.elasticsearch.entities; package org.springframework.data.elasticsearch.entities;
import static org.springframework.data.elasticsearch.annotations.FieldType.*; 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; import java.util.Date;
@@ -19,7 +19,7 @@ public class SampleDateMappingEntity {
@Id @Id
private String 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 String message;
@Field(type = Date, format = DateFormat.custom, pattern = "dd.MM.yyyy hh:mm") @Field(type = Date, format = DateFormat.custom, pattern = "dd.MM.yyyy hh:mm")
@@ -23,6 +23,7 @@ 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 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;
@@ -34,21 +35,23 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*;
/** /**
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Chris White
*/ */
@Setter @Setter
@Getter @Getter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ToString
@Builder @Builder
@Document(indexName = "test-index-sample", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1") @Document(indexName = "test-index-sample", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1")
public class SampleEntity { public class SampleEntity {
@Id @Id
private String id; private String id;
@Field(type = text, store = true, fielddata = true) @Field(type = Text, store = true, fielddata = true)
private String type; private String type;
@Field(type = text, store = true, fielddata = true) @Field(type = Text, store = true, fielddata = true)
private String message; private String message;
private int rate; private int rate;
@ScriptedField @ScriptedField
@@ -48,7 +48,7 @@ public class SampleEntityUUIDKeyed {
@Id @Id
private UUID id; private UUID id;
private String type; private String type;
@Field(type = FieldType.text, fielddata = true) @Field(type = FieldType.Text, fielddata = true)
private String message; private String message;
private int rate; private int rate;
@ScriptedField @ScriptedField
@@ -15,7 +15,7 @@
*/ */
package org.springframework.data.elasticsearch.entities; 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.Document;
import org.springframework.data.elasticsearch.annotations.Field; 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") @Document(indexName = "test-index-sample-inherited", type = "mapping", shards = 1, replicas = 0, refreshInterval = "-1")
public class SampleInheritedEntity extends AbstractInheritedEntity { 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; private String message;
public String getMessage() { public String getMessage() {
@@ -15,7 +15,7 @@
*/ */
package org.springframework.data.elasticsearch.entities; 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.Id;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
@@ -31,7 +31,7 @@ public class SampleMappingEntity {
@Id @Id
private String 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 String message;
private NestedEntity nested; private NestedEntity nested;
@@ -54,7 +54,7 @@ public class SampleMappingEntity {
static class NestedEntity { static class NestedEntity {
@Field(type = text) @Field(type = Text)
private String someField; private String someField;
public String getSomeField() { public String getSomeField() {
@@ -15,7 +15,7 @@
*/ */
package org.springframework.data.elasticsearch.entities; 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.Id;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;
@@ -31,7 +31,7 @@ public class SampleTransientEntity {
@Id @Id
private String 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 String message;
@Transient @Transient
@@ -47,6 +47,7 @@ import static org.springframework.data.domain.Sort.Direction.*;
* @author Mohsin Husen * @author Mohsin Husen
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Michael Wirth
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/simple-repository-test.xml") @ContextConfiguration("classpath:/simple-repository-test.xml")
@@ -274,6 +275,19 @@ public class SimpleElasticsearchRepositoryTests {
assertEquals(exist, true); 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 @Test
public void shouldReturnResultsForGivenSearchQuery() { public void shouldReturnResultsForGivenSearchQuery() {
// given // given
@@ -45,6 +45,7 @@ import static org.junit.Assert.*;
* @author Mohsin Husen * @author Mohsin Husen
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Michael Wirth
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/simple-repository-test.xml") @ContextConfiguration("classpath:/simple-repository-test.xml")
@@ -262,6 +263,19 @@ public class UUIDElasticsearchRepositoryTests {
assertEquals(exist, true); 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 @Test
public void shouldDeleteAll() { public void shouldDeleteAll() {
// when // when