1
0
mirror of synced 2026-09-02 22:21:01 +00:00

Compare commits

...

80 Commits

Author SHA1 Message Date
Mark Paluch 2d2a2b6268 DATAES-925 - Release version 3.2.11 (Moore SR11). 2020-10-28 11:44:38 +01:00
Mark Paluch c1219da439 DATAES-925 - Prepare 3.2.11 (Moore SR11). 2020-10-28 11:44:08 +01:00
Mark Paluch 3203f29f08 DATAES-925 - Updated changelog. 2020-10-28 11:44:04 +01:00
Mark Paluch f18bea58f1 DATAES-958 - Updated changelog. 2020-10-28 11:32:34 +01:00
Peter-Josef Meisch 1a415958ad DATAES-961 - Upgrade to Elasticsearch 6.8.13.
Original PR: #544
2020-10-26 22:18:28 +01:00
Christoph Strobl c26f8bf8e4 DATAES-927 - Updated changelog. 2020-10-14 14:51:50 +02:00
Peter-Josef Meisch ca6ef58195 DATAES-937 - Repository queries with IN filters fail with empty input list.
Original PR: #525

(cherry picked from commit 7117e5d70d)
2020-09-25 09:23:35 +02:00
Peter-Josef Meisch 6bd96dc4d8 DATAES-896 - Use mainField property of @MultiField annotation.
Original PR: #524
2020-09-24 21:19:07 +02:00
Mark Paluch 82c314206a DATAES-904 - Updated changelog. 2020-09-16 14:12:11 +02:00
Mark Paluch 2d2e4408d2 DATAES-905 - Updated changelog. 2020-09-16 12:16:38 +02:00
Mark Paluch 5c7b2a07ac DATAES-888 - After release cleanups. 2020-09-16 11:19:27 +02:00
Mark Paluch fa364c8bd4 DATAES-888 - Prepare next development iteration. 2020-09-16 11:19:24 +02:00
Mark Paluch 679be76847 DATAES-888 - Release version 3.2.10 (Moore SR10). 2020-09-16 10:53:23 +02:00
Mark Paluch 1fea502355 DATAES-888 - Prepare 3.2.10 (Moore SR10). 2020-09-16 10:52:54 +02:00
Mark Paluch 52e725f9a2 DATAES-888 - Updated changelog. 2020-09-16 10:52:51 +02:00
Mark Paluch 160fd851e6 DATAES-887 - Updated changelog. 2020-09-16 10:39:04 +02:00
Peter-Josef Meisch a409440e4e DATAES-903 - Update to Elasticsearch 6.8.12.
Original PR: #511
2020-08-24 21:06:58 +02:00
Mark Paluch 83d5a58737 DATAES-890 - Updated changelog. 2020-08-12 13:25:55 +02:00
Mark Paluch 1b62e311fd DATAES-872 - Updated changelog. 2020-08-12 12:01:26 +02:00
Peter-Josef Meisch bf5eaae357 DATAES-892 - Fix ElasticsearchEntityMapper recursive descent when reading Map objects. 2020-07-29 21:17:21 +02:00
Mark Paluch ee660bb208 DATAES-862 - Updated changelog. 2020-07-22 10:38:05 +02:00
Mark Paluch e01d618c83 DATAES-861 - After release cleanups. 2020-07-22 10:07:20 +02:00
Mark Paluch d48bfcc820 DATAES-861 - Prepare next development iteration. 2020-07-22 10:07:18 +02:00
Mark Paluch c87e4a2fa5 DATAES-861 - Release version 3.2.9 (Moore SR9). 2020-07-22 09:55:56 +02:00
Mark Paluch 3770f37855 DATAES-861 - Prepare 3.2.9 (Moore SR9). 2020-07-22 09:55:30 +02:00
Mark Paluch c5287dc326 DATAES-861 - Updated changelog. 2020-07-22 09:55:26 +02:00
Mark Paluch 53a9181d5f DATAES-860 - Updated changelog. 2020-07-22 09:44:35 +02:00
Mark Paluch 0c36132c5c DATAES-824 - Updated changelog. 2020-06-25 12:00:24 +02:00
Mark Paluch 33174ff28e DATAES-823 - Updated changelog. 2020-06-10 14:31:03 +02:00
Mark Paluch 67972f5b29 DATAES-807 - After release cleanups. 2020-06-10 12:29:17 +02:00
Mark Paluch e943a815b9 DATAES-807 - Prepare next development iteration. 2020-06-10 12:29:14 +02:00
Mark Paluch 43e8e26b5b DATAES-807 - Release version 3.2.8 (Moore SR8). 2020-06-10 12:11:27 +02:00
Mark Paluch 43133d6a9f DATAES-807 - Prepare 3.2.8 (Moore SR8). 2020-06-10 12:11:00 +02:00
Mark Paluch 5184fc44a7 DATAES-807 - Updated changelog. 2020-06-10 12:10:58 +02:00
Mark Paluch 93b353e3bf DATAES-806 - Updated changelog. 2020-06-10 11:22:52 +02:00
Peter-Josef Meisch 401893eb34 DATAES-851 - Upgrade to Elasticsearch 6.8.10.
Original PR: #474
2020-06-05 14:22:58 +02:00
Peter-Josef Meisch b19af5cf17 DATAES-837 - Update to Elasticsearch 6.8.9.
Original PR: #464
2020-05-21 06:22:35 +02:00
Peter-Josef Meisch fd713bfc8e DATAES-822 - Convert Reactive Client exceptions to ElasticsearchStatusException. (#453)
Original PR: #453
2020-05-12 06:07:21 +02:00
Peter-Josef Meisch c3bde816fe DATES-821 - Fix code for adding an alias.
Original PR: #452
2020-05-10 20:08:05 +02:00
Greg Turnquist 187a8b9e15 DATAES-811 - Remove Travis CI. 2020-05-04 15:30:29 -05:00
Peter-Josef Meisch ee02073142 DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses. 2020-05-03 04:46:01 +02:00
Peter-Josef Meisch 0df58615e9 DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses. (#446)
Original PR: #445

(cherry picked from commit e605cad688)
2020-05-03 04:25:36 +02:00
Peter-Josef Meisch a69658dc8b DATAES-776 - Adapt RestClients class to change in InetSocketAddress class in JDK14. 2020-04-30 17:47:11 +02:00
Mark Paluch f3e83bf4ae DATAES-774 - Updated changelog. 2020-04-28 15:12:26 +02:00
Mark Paluch 88552cfe1a DATAES-770 - After release cleanups. 2020-04-28 14:45:30 +02:00
Mark Paluch 40ecf9211d DATAES-770 - Prepare next development iteration. 2020-04-28 14:45:29 +02:00
Mark Paluch bd898f0363 DATAES-770 - Release version 3.2.7 (Moore SR7). 2020-04-28 14:35:55 +02:00
Mark Paluch b1a6dc524c DATAES-770 - Prepare 3.2.7 (Moore SR7). 2020-04-28 14:35:25 +02:00
Mark Paluch 197956c4d4 DATAES-770 - Updated changelog. 2020-04-28 14:35:23 +02:00
Mark Paluch bc0bead9b8 DATAES-755 - Updated changelog. 2020-04-28 11:59:02 +02:00
Peter-Josef Meisch 1459dd491d DATAES-778 - Fix SSL setup in the reactive client.
Original PR: #429

(cherry picked from commit 539c1ee6e7)
2020-04-16 21:47:10 +02:00
Peter-Josef Meisch 952e0c8985 DATAES-780 - Upgrade 3.2.x to Elasticsearch 6.8.8.
Original PR: #420
2020-04-04 16:14:45 +02:00
Mark Paluch f6caa731dd DATAES-762 - Updated changelog. 2020-03-31 15:08:50 +02:00
Mark Paluch b7dbdbf0e0 DATAES-756 - After release cleanups. 2020-03-25 10:58:27 +01:00
Mark Paluch 80a61e27c4 DATAES-756 - Prepare next development iteration. 2020-03-25 10:58:26 +01:00
Mark Paluch 0ce8e7ce0e DATAES-756 - Release version 3.2.6 (Moore SR6). 2020-03-25 10:46:02 +01:00
Mark Paluch fde9f42735 DATAES-756 - Prepare 3.2.6 (Moore SR6). 2020-03-25 10:45:35 +01:00
Mark Paluch 6b2ad6cdc6 DATAES-756 - Updated changelog. 2020-03-25 10:45:34 +01:00
Mark Paluch 7e7ceb885d DATAES-769 - Upgrade to Elasticsearch 6.8.7. 2020-03-23 16:45:41 +01:00
Peter-Josef Meisch 54c80f3375 DATAES-763 - Allow map properties in entity with null values. 2020-03-22 08:58:11 +01:00
Peter-Josef Meisch 39b318caa7 DATAES-765 - Pageable.unpaged() is not used to build a query returning all documents.
Original PR: #409
2020-03-20 19:07:58 +01:00
Peter-Josef Meisch 17af36702f DATAES-764 - Adapt to JUnit4. 2020-03-18 20:49:28 +01:00
Sascha Woo e22e2bbfc3 DATAES-764 - StreamQueries#streamResults does not clear scroll context when finished.
Original PR: #406

(cherry picked from commit f103bdb9d8)
2020-03-18 20:39:30 +01:00
Jens Schauder b11f8d2c38 DATAES-744 - Updated changelog. 2020-03-11 09:59:33 +01:00
Peter-Josef Meisch 6062896568 DATAES-758 - Fix documentation for @Query annotation.
Original PR: #402
2020-03-06 18:44:49 +01:00
Mark Paluch 33057cafb1 DATAES-730 - After release cleanups. 2020-02-26 11:54:09 +01:00
Mark Paluch 643b8b1e64 DATAES-730 - Prepare next development iteration. 2020-02-26 11:54:08 +01:00
Mark Paluch 8f5947bfc7 DATAES-730 - Release version 3.2.5 (Moore SR5). 2020-02-26 11:38:18 +01:00
Mark Paluch af78e0bf3d DATAES-730 - Prepare 3.2.5 (Moore SR5). 2020-02-26 11:37:58 +01:00
Mark Paluch e4f1c8ba58 DATAES-730 - Updated changelog. 2020-02-26 11:37:57 +01:00
Mark Paluch be4924a214 DATAES-729 - Updated changelog. 2020-02-26 11:31:49 +01:00
Mark Paluch 55119989f7 DATAES-752 - Upgrade to Elasticsearch 6.8.6. 2020-02-24 09:06:56 +01:00
Peter-Josef Meisch 068de487b2 DATAES-741 - Tests fail due to Elasticsearch cluster 'blocks' on nearly-full file-systems. 2020-02-15 16:32:58 +01:00
Peter-Josef Meisch bacad5ca0c DATAES-214 - Polishing. 2020-02-12 20:58:41 +01:00
Alexander Shabunevich 864d41cb01 DATAES-214 - ElasticsearchTemplate's prepareSearch(Query query) method should use getOffset().
Original PR: #392
2020-02-12 20:55:36 +01:00
Mark Paluch 8dd7cfcc6e DATAES-732 - Updated changelog. 2020-02-12 15:05:02 +01:00
Mark Paluch 868664aa78 DATAES-731 - Updated changelog. 2020-01-17 09:58:35 +01:00
Mark Paluch 5f9eab9a97 DATAES-663 - Updated changelog. 2020-01-16 16:12:38 +01:00
Mark Paluch 090ed0be5c DATAES-704 - After release cleanups. 2020-01-15 12:48:23 +01:00
Mark Paluch fc9e47ccd7 DATAES-704 - Prepare next development iteration. 2020-01-15 12:48:22 +01:00
46 changed files with 1108 additions and 253 deletions
-8
View File
@@ -1,8 +0,0 @@
dist: xenial
language: java
jdk:
- openjdk8
script: "mvn clean dependency:list test -Dsort -U -B"
+5 -4
View File
@@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.4.RELEASE</version>
<version>3.2.11.RELEASE</version>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.2.4.RELEASE</version>
<version>2.2.11.RELEASE</version>
</parent>
<name>Spring Data Elasticsearch</name>
@@ -19,9 +19,9 @@
<properties>
<commonslang>2.6</commonslang>
<elasticsearch>6.8.4</elasticsearch>
<elasticsearch>6.8.13</elasticsearch>
<log4j>2.9.1</log4j>
<springdata.commons>2.2.4.RELEASE</springdata.commons>
<springdata.commons>2.2.11.RELEASE</springdata.commons>
<netty>4.1.39.Final</netty>
<java-module-name>spring.data.elasticsearch</java-module-name>
</properties>
@@ -296,6 +296,7 @@
<useFile>false</useFile>
<includes>
<include>**/*Tests.java</include>
<include>**/*Test.java</include>
</includes>
<systemPropertyVariables>
<es.set.netty.runtime.available.processors>false</es.set.netty.runtime.available.processors>
+1 -1
View File
@@ -35,7 +35,7 @@ The following table shows the Elasticsearch versions that are used by Spring Dat
[cols="^,^,^,^",options="header"]
|===
|Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot
|Moore |3.2.x |6.8.4 |2.2.x
|Moore |3.2.x |6.8.13 |2.2.x
|Lovelace |3.1.x |6.2.2|2.1.x
|Kayfootnote:oom[Out of maintenance]|3.0.xfootnote:oom[] |5.5.0 |2.0.xfootnote:oom[]
|Ingallsfootnote:oom[]|2.1.xfootnote:oom[] |2.4.0 |1.5.xfootnote:oom[]
@@ -8,7 +8,7 @@ The Elasticsearch module supports all basic query building feature as string que
=== Declared queries
Deriving the query from the method name is not always sufficient and/or may result in unreadable method names. In this case one might make either use of `@Query` annotation (see <<elasticsearch.query-methods.at-query>> ).
Deriving the query from the method name is not always sufficient and/or may result in unreadable method names. In this case one might make use of the `@Query` annotation (see <<elasticsearch.query-methods.at-query>> ).
[[elasticsearch.query-methods.criterions]]
== Query creation
@@ -29,12 +29,14 @@ The method name above will be translated into the following Elasticsearch json q
[source]
----
{ "bool" :
{ "must" :
[
{ "field" : {"name" : "?"} },
{ "field" : {"price" : "?"} }
]
{
"query": {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}
}
----
@@ -48,80 +50,184 @@ A list of supported keywords for Elasticsearch is shown below.
| Sample
| Elasticsearch Query String| `And`
| `findByNameAndPrice`
| `{"bool" : {"must" : [ {"field" : {"name" : "?"}},
{"field" : {"price" : "?"}} ]}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}}`
| `Or`
| `findByNameOrPrice`
| `{"bool" : {"should" : [ {"field" : {"name" : "?"}},
{"field" : {"price" : "?"}} ]}}`
| `{ "query" : {
"bool" : {
"should" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}}`
| `Is`
| `findByName`
| `{"bool" : {"must" : {"field" : {"name" : "?"}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
]
}
}}`
| `Not`
| `findByNameNot`
| `{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}`
| `{ "query" : {
"bool" : {
"must_not" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
]
}
}}`
| `Between`
| `findByPriceBetween`
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } }
]
}
}}`
| `LessThan`
| `findByPriceLessThan`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } }
]
}
}}`
| `LessThanEqual`
| `findByPriceLessThan`
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
null,"to" : ?,"include_lower" : true,"include_upper" :
true}}}}}`
| `findByPriceLessThanEqual`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
]
}
}}`
| `GreaterThan`
| `findByPriceGreaterThan`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } }
]
}
}}`
| `GreaterThanEqual`
| `findByPriceGreaterThan`
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
?,"to" : null,"include_lower" : true,"include_upper" :
true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
]
}
}}`
| `Before`
| `findByPriceBefore`
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
null,"to" : ?,"include_lower" : true,"include_upper" :
true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
]
}
}}`
| `After`
| `findByPriceAfter`
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
?,"to" : null,"include_lower" : true,"include_upper" :
true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
]
}
}}`
| `Like`
| `findByNameLike`
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
"?*","analyze_wildcard" : true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}`
| `StartingWith`
| `findByNameStartingWith`
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
"?*","analyze_wildcard" : true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}`
| `EndingWith`
| `findByNameEndingWith`
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
"*?","analyze_wildcard" : true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}`
| `Contains/Containing`
| `findByNameContaining`
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
"*?*","analyze_wildcard" : true}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "\*?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}`
| `In`
| `findByNameIn(Collection<String>names)`
| `{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{"bool" : {"must" : [
{"terms" : {"name" : ["?","?"]}}
]
}
}
]
}
}}`
| `NotIn`
| `findByNameNotIn(Collection<String>names)`
| `{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
{"name" : "?"}}}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{"bool" : {"must_not" : [
{"terms" : {"name" : ["?","?"]}}
]
}
}
]
}
}}`
| `Near`
| `findByStoreNear`
@@ -129,18 +235,45 @@ A list of supported keywords for Elasticsearch is shown below.
| `True`
| `findByAvailableTrue`
| `{"bool" : {"must" : {"field" : {"available" : true}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
]
}
}}`
| `False`
| `findByAvailableFalse`
| `{"bool" : {"must" : {"field" : {"available" : false}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "false", "fields" : [ "available" ] } }
]
}
}}`
| `OrderBy`
| `findByAvailableTrueOrderByNameDesc`
| `{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
{"must" : {"field" : {"available" : true}}}}`
| `{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
]
}
}, "sort":[{"name":{"order":"desc"}}]
}`
|===
== Method return types
Repository methods can be defined to have the following return types for returning multiple Elements:
* `List<T>`
* `Stream<T>`
* `AggregatedPage<T>`
[[elasticsearch.query-methods.at-query]]
== Using @Query Annotation
@@ -149,8 +282,21 @@ A list of supported keywords for Elasticsearch is shown below.
[source,java]
----
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("{\"bool\" : {\"must\" : {\"field\" : {\"name\" : \"?0\"}}}}")
@Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}")
Page<Book> findByName(String name,Pageable pageable);
}
----
The String that is set as the annotation argument must be a valid Elasticsearch JSON query. It will be sent to Easticsearch as value of the query element; if for example the function is called with the parameter _John_, it would produce the following query body:
[source,json]
----
{
"query": {
"match": {
"name": {
"query": "John"
}
}
}
}
----
====
@@ -135,7 +135,8 @@ public final class RestClients {
}
private static List<String> formattedHosts(List<InetSocketAddress> hosts, boolean useSsl) {
return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it).collect(Collectors.toList());
return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ':' + it.getPort())
.collect(Collectors.toList());
}
/**
@@ -16,7 +16,9 @@
package org.springframework.data.elasticsearch.client.reactive;
import io.netty.channel.ChannelOption;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.IdentityCipherSuiteFilter;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
@@ -45,6 +47,7 @@ import java.util.function.Function;
import javax.net.ssl.SSLContext;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
@@ -94,7 +97,6 @@ import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.reactivestreams.Publisher;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.ClientLogger;
import org.springframework.data.elasticsearch.client.ElasticsearchHost;
@@ -113,7 +115,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse;
@@ -199,7 +200,6 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
}
if (!soTimeout.isNegative()) {
tcpClient = tcpClient.doOnConnected(connection -> connection //
.addHandlerLast(new ReadTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS))
.addHandlerLast(new WriteTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS)));
@@ -210,11 +210,16 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
if (clientConfiguration.useSsl()) {
httpClient = httpClient.secure(sslConfig -> {
Optional<SSLContext> sslContext = clientConfiguration.getSslContext();
Optional<SSLContext> sslContext = clientConfiguration.getSslContext();
sslContext.ifPresent(it -> sslConfig.sslContext(new JdkSslContext(it, true, ClientAuth.NONE)));
});
if (sslContext.isPresent()) {
httpClient = httpClient.secure(sslContextSpec -> {
sslContextSpec.sslContext(new JdkSslContext(sslContext.get(), true, null, IdentityCipherSuiteFilter.INSTANCE,
ApplicationProtocolConfig.DISABLED, ClientAuth.NONE, null, false));
});
} else {
httpClient = httpClient.secure();
}
scheme = "https";
}
@@ -440,6 +445,7 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.http.HttpHeaders, org.elasticsearch.index.reindex.DeleteByQueryRequest)
*/
@Override
public Mono<BulkByScrollResponse> deleteBy(HttpHeaders headers, DeleteByQueryRequest deleteRequest) {
return sendRequest(deleteRequest, RequestCreator.deleteByQuery(), BulkByScrollResponse.class, headers) //
@@ -673,6 +679,12 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
return handleServerError(request, response);
}
if (response.statusCode().is4xxClientError()) {
ClientLogger.logRawResponse(logId, response.statusCode());
return handleClientError(logId, request, response, responseType);
}
return response.body(BodyExtractors.toMono(byte[].class)) //
.map(it -> new String(it, StandardCharsets.UTF_8)) //
.doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) //
@@ -709,13 +721,68 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content);
}
private static <T> Publisher<? extends T> handleServerError(Request request, ClientResponse response) {
private <T> Publisher<? extends T> handleServerError(Request request, ClientResponse response) {
return Mono.error(
new HttpServerErrorException(response.statusCode(), String.format("%s request to %s returned error code %s.",
request.getMethod(), request.getEndpoint(), response.statusCode().value())));
RestStatus status = RestStatus.fromCode(response.statusCode().value());
return Mono.error(new ElasticsearchStatusException(String.format("%s request to %s returned error code %s.",
request.getMethod(), request.getEndpoint(), response.statusCode().value()), status));
}
private <T> Publisher<? extends T> handleClientError(String logId, Request request, ClientResponse response,
Class<T> responseType) {
return response.body(BodyExtractors.toMono(byte[].class)) //
.map(bytes -> new String(bytes, StandardCharsets.UTF_8)) //
.flatMap(content -> {
String mediaType = response.headers().contentType().map(MediaType::toString)
.orElse(XContentType.JSON.mediaType());
RestStatus status = RestStatus.fromCode(response.statusCode().value());
try {
ElasticsearchException exception = getElasticsearchException(response, content, mediaType);
if (exception != null) {
StringBuilder sb = new StringBuilder();
buildExceptionMessages(sb, exception);
return Mono.error(new ElasticsearchStatusException(sb.toString(), status, exception));
}
} catch (Exception e) {
return Mono.error(new ElasticsearchStatusException(content, status));
}
return Mono.just(content);
}).doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) //
.flatMap(content -> doDecode(response, responseType, content));
}
// region ElasticsearchException helper
@Nullable
private ElasticsearchException getElasticsearchException(ClientResponse response, String content, String mediaType)
throws IOException {
XContentParser parser = createParser(mediaType, content);
// we have a JSON object with an error and a status field
XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT
do {
token = parser.nextToken();
if (parser.currentName().equals("error")) {
return ElasticsearchException.failureFromXContent(parser);
}
} while (token == XContentParser.Token.FIELD_NAME);
return null;
}
private static void buildExceptionMessages(StringBuilder sb, Throwable t) {
sb.append(t.getMessage());
for (Throwable throwable : t.getSuppressed()) {
sb.append(", ");
buildExceptionMessages(sb, throwable);
}
}
// endregion
// region internal classes
static class RequestCreator {
static Function<SearchRequest, Request> search() {
@@ -769,7 +836,7 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
try {
return RequestConverters.deleteByQuery(request);
} catch (IOException e) {
throw new ElasticsearchException("Could not parse request", e);
throw new org.springframework.data.elasticsearch.ElasticsearchException("Could not parse request", e);
}
};
}
@@ -781,7 +848,7 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
try {
return RequestConverters.bulk(request);
} catch (IOException e) {
throw new ElasticsearchException("Could not parse request", e);
throw new org.springframework.data.elasticsearch.ElasticsearchException("Could not parse request", e);
}
};
}
@@ -885,4 +952,5 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
}
}
}
// endregion
}
@@ -15,6 +15,8 @@ import org.springframework.util.StringUtils;
*/
public abstract class AbstractElasticsearchTemplate {
static final Integer INDEX_MAX_RESULT_WINDOW = 10_000;
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class);
protected ElasticsearchConverter elasticsearchConverter;
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core;
import static org.elasticsearch.index.query.Operator.AND;
import static org.elasticsearch.index.query.Operator.*;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.springframework.data.elasticsearch.core.query.Criteria.*;
@@ -25,7 +25,9 @@ import java.util.List;
import java.util.ListIterator;
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
import org.elasticsearch.index.query.*;
import org.apache.lucene.queryparser.flexible.standard.QueryParserUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.util.Assert;
@@ -39,7 +41,6 @@ import org.springframework.util.Assert;
*/
class CriteriaQueryProcessor {
QueryBuilder createQueryFromCriteria(Criteria criteria) {
if (criteria == null)
return null;
@@ -104,7 +105,6 @@ class CriteriaQueryProcessor {
return query;
}
private QueryBuilder createQueryFragmentForCriteria(Criteria chainedCriteria) {
if (chainedCriteria.getQueryCriteriaEntries().isEmpty())
return null;
@@ -131,8 +131,8 @@ class CriteriaQueryProcessor {
return query;
}
private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry,/* OperationKey key, Object value,*/ String fieldName) {
private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry,
/* OperationKey key, Object value,*/ String fieldName) {
Object value = entry.getValue();
if (value == null) {
return null;
@@ -180,17 +180,15 @@ class CriteriaQueryProcessor {
query = fuzzyQuery(fieldName, searchText);
break;
case IN:
query = boolQuery();
collection = (Iterable<Object>) value;
for (Object item : collection) {
((BoolQueryBuilder) query).should(queryStringQuery(item.toString()).field(fieldName));
if (value instanceof Iterable) {
Iterable<?> iterable = (Iterable<?>) value;
query = queryStringQuery(orQueryString(iterable)).field(fieldName);
}
break;
case NOT_IN:
query = boolQuery();
collection = (Iterable<Object>) value;
for (Object item : collection) {
((BoolQueryBuilder) query).mustNot(queryStringQuery(item.toString()).field(fieldName));
if (value instanceof Iterable) {
Iterable<?> iterable = (Iterable<?>) value;
query = queryStringQuery("NOT(" + orQueryString(iterable) + ')').field(fieldName);
}
break;
}
@@ -203,4 +201,23 @@ class CriteriaQueryProcessor {
}
query.boost(boost);
}
private static String orQueryString(Iterable<?> iterable) {
StringBuilder sb = new StringBuilder();
for (Object item : iterable) {
if (item != null) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append('"');
sb.append(QueryParserUtil.escape(item.toString()));
sb.append('"');
}
}
return sb.toString();
}
}
@@ -15,8 +15,6 @@
*/
package org.springframework.data.elasticsearch.core;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import lombok.RequiredArgsConstructor;
import java.io.IOException;
@@ -52,6 +50,8 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
/**
* Elasticsearch specific {@link EntityReader} & {@link EntityWriter} implementation based on domain type
@@ -241,27 +241,31 @@ public class ElasticsearchEntityMapper implements
Map<String, Object> target = new LinkedHashMap<>();
for (Entry<String, Object> entry : source.entrySet()) {
if (isSimpleType(entry.getValue())) {
target.put(entry.getKey(),
readSimpleValue(entry.getValue(), targetType.isMap() ? targetType.getComponentType() : targetType));
String entryKey = entry.getKey();
Object entryValue = entry.getValue();
if (entryValue == null) {
target.put(entryKey, null);
} else if (isSimpleType(entryValue)) {
target.put(entryKey,
readSimpleValue(entryValue, targetType.isMap() ? targetType.getComponentType() : targetType));
} else {
ElasticsearchPersistentEntity<?> targetEntity = computeGenericValueTypeForRead(property, entry.getValue());
ElasticsearchPersistentEntity<?> targetEntity = computeGenericValueTypeForRead(property, entryValue);
if (targetEntity.getTypeInformation().isMap()) {
Map<String, Object> valueMap = (Map) entry.getValue();
Map<String, Object> valueMap = (Map) entryValue;
if (typeMapper.containsTypeInformation(valueMap)) {
target.put(entry.getKey(), readEntity(targetEntity, (Map) entry.getValue()));
target.put(entryKey, readEntity(targetEntity, (Map) entryValue));
} else {
target.put(entry.getKey(), readValue(valueMap, property, targetEntity.getTypeInformation()));
target.put(entryKey, readValue(valueMap, property, targetEntity.getTypeInformation()));
}
} else if (targetEntity.getTypeInformation().isCollectionLike()) {
target.put(entry.getKey(),
readValue(entry.getValue(), property, targetEntity.getTypeInformation().getActualType()));
target.put(entryKey, readValue(entryValue, property, targetEntity.getTypeInformation().getActualType()));
} else {
target.put(entry.getKey(), readEntity(targetEntity, (Map) entry.getValue()));
target.put(entryKey, readEntity(targetEntity, (Map) entryValue));
}
}
}
@@ -281,13 +285,18 @@ public class ElasticsearchEntityMapper implements
for (Object value : source) {
if (isSimpleType(value)) {
if (value == null) {
target.add(null);
} else if (isSimpleType(value)) {
target.add(
readSimpleValue(value, targetType.getComponentType() != null ? targetType.getComponentType() : targetType));
} else {
if (value instanceof List) {
target.add(readValue(value, property, property.getTypeInformation().getActualType()));
} else if (value instanceof Map) {
target
.add(readMapValue((Map<String, Object>) value, property, property.getTypeInformation().getActualType()));
} else {
target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map) value));
}
@@ -493,7 +502,14 @@ public class ElasticsearchEntityMapper implements
if (!typeHint.getActualType().getType().equals(Object.class)
&& isSimpleType(typeHint.getMapValueType().getType())) {
mapSource.forEach(it -> target.put(it.getKey(), getWriteSimpleValue(it.getValue())));
mapSource.forEach(it -> {
if (it.getValue() == null) {
target.put(it.getKey(), null);
} else {
target.put(it.getKey(), getWriteSimpleValue(it.getValue()));
}
});
} else {
mapSource.forEach(it -> {
@@ -143,6 +143,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @author Peter-Josef Meisch
* @author Mathias Teier
* @author Gyula Attila Csorogi
* @author Alexander Shabunevich
*/
public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
implements ElasticsearchOperations, EsClient<RestHighLevelClient>, ApplicationContextAware {
@@ -208,11 +209,17 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
aliasAction.filter(query.getFilterBuilder());
} else if (query.getFilter() != null) {
aliasAction.filter(query.getFilter());
} else if (hasText(query.getRouting())) {
}
if (hasText(query.getRouting())) {
aliasAction.routing(query.getRouting());
} else if (hasText(query.getSearchRouting())) {
}
if (hasText(query.getSearchRouting())) {
aliasAction.searchRouting(query.getSearchRouting());
} else if (hasText(query.getIndexRouting())) {
}
if (hasText(query.getIndexRouting())) {
aliasAction.indexRouting(query.getIndexRouting());
}
@@ -1338,8 +1345,17 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
}
if (query.getPageable().isPaged()) {
startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
long offset = query.getPageable().getOffset();
if (offset > Integer.MAX_VALUE) {
throw new IllegalArgumentException(String.format("Offset must not be more than %d", Integer.MAX_VALUE));
}
startRecord = (int) offset;
sourceBuilder.size(query.getPageable().getPageSize());
} else {
startRecord = 0;
sourceBuilder.size(INDEX_MAX_RESULT_WINDOW);
}
sourceBuilder.from(startRecord);
@@ -123,6 +123,7 @@ import org.springframework.util.StringUtils;
* @author Martin Choraine
* @author Farid Azaza
* @author Gyula Attila Csorogi
* @author Alexander Shabunevich
*/
public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
@@ -189,13 +190,20 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
aliasAction.filter(query.getFilterBuilder());
} else if (query.getFilter() != null) {
aliasAction.filter(query.getFilter());
} else if (!StringUtils.isEmpty(query.getRouting())) {
}
if (!StringUtils.isEmpty(query.getRouting())) {
aliasAction.routing(query.getRouting());
} else if (!StringUtils.isEmpty(query.getSearchRouting())) {
}
if (!StringUtils.isEmpty(query.getSearchRouting())) {
aliasAction.searchRouting(query.getSearchRouting());
} else if (!StringUtils.isEmpty(query.getIndexRouting())) {
}
if (!StringUtils.isEmpty(query.getIndexRouting())) {
aliasAction.indexRouting(query.getIndexRouting());
}
return client.admin().indices().prepareAliases().addAliasAction(aliasAction).execute().actionGet().isAcknowledged();
}
@@ -1115,8 +1123,17 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
}
if (query.getPageable().isPaged()) {
startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
long offset = query.getPageable().getOffset();
if (offset > Integer.MAX_VALUE) {
throw new IllegalArgumentException(String.format("Offset must not be more than %d", Integer.MAX_VALUE));
}
startRecord = (int) offset;
searchRequestBuilder.setSize(query.getPageable().getPageSize());
} else {
startRecord = 0;
searchRequestBuilder.setSize(INDEX_MAX_RESULT_WINDOW);
}
searchRequestBuilder.setFrom(startRecord);
@@ -367,6 +367,8 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
request.source(searchSourceBuilder);
} else {
searchSourceBuilder.from(0);
searchSourceBuilder.size(AbstractElasticsearchTemplate.INDEX_MAX_RESULT_WINDOW);
request.source(searchSourceBuilder);
}
return request;
@@ -2,12 +2,14 @@
package org.springframework.data.elasticsearch.core;
import org.springframework.data.domain.Page;
import org.springframework.lang.Nullable;
/**
* @author Artur Konczak
* @author Peter-Josef Meisch
* @author Sascha Woo
*/
public interface ScrolledPage<T> extends Page<T> {
String getScrollId();
String getScrollId();
}
@@ -21,11 +21,13 @@ import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.data.util.CloseableIterator;
import org.springframework.util.Assert;
/**
* Utility to support streaming queries.
*
* @author Mark Paluch
* @author Sascha Woo
* @since 3.2
*/
abstract class StreamQueries {
@@ -33,72 +35,71 @@ abstract class StreamQueries {
/**
* Stream query results using {@link ScrolledPage}.
*
* @param page the initial page.
* @param continueFunction continuation function accepting the current scrollId.
* @param clearScroll cleanup function accepting the current scrollId.
* @param page the initial scrolled page.
* @param continueScrollFunction function to continue scrolling applies to the current scrollId.
* @param clearScrollConsumer consumer to clear the scroll context by accepting the current scrollId.
* @param <T>
* @return the {@link CloseableIterator}.
*/
static <T> CloseableIterator<T> streamResults(ScrolledPage<T> page,
Function<String, ScrolledPage<T>> continueFunction, Consumer<String> clearScroll) {
Function<String, ScrolledPage<T>> continueScrollFunction, Consumer<String> clearScrollConsumer) {
Assert.notNull(page, "page must not be null.");
Assert.notNull(page.getScrollId(), "scrollId must not be null.");
Assert.notNull(continueScrollFunction, "continueScrollFunction must not be null.");
Assert.notNull(clearScrollConsumer, "clearScrollConsumer must not be null.");
return new CloseableIterator<T>() {
/** As we couldn't retrieve single result with scroll, store current hits. */
private volatile Iterator<T> currentHits = page.iterator();
/** The scroll id. */
// As we couldn't retrieve single result with scroll, store current hits.
private volatile Iterator<T> scrollHits = page.iterator();
private volatile String scrollId = page.getScrollId();
/** If stream is finished (ie: cluster returns no results. */
private volatile boolean finished = !currentHits.hasNext();
private volatile boolean continueScroll = scrollHits.hasNext();
@Override
public void close() {
try {
// Clear scroll on cluster only in case of error (cause elasticsearch auto clear scroll when it's done)
if (!finished && scrollId != null && currentHits != null && currentHits.hasNext()) {
clearScroll.accept(scrollId);
}
clearScrollConsumer.accept(scrollId);
} finally {
currentHits = null;
scrollHits = null;
scrollId = null;
}
}
@Override
public boolean hasNext() {
// Test if stream is finished
if (finished) {
if (!continueScroll) {
return false;
}
// Test if it remains hits
if (currentHits == null || !currentHits.hasNext()) {
// Do a new request
ScrolledPage<T> scroll = continueFunction.apply(scrollId);
// Save hits and scroll id
currentHits = scroll.iterator();
finished = !currentHits.hasNext();
scrollId = scroll.getScrollId();
if (!scrollHits.hasNext()) {
ScrolledPage<T> nextPage = continueScrollFunction.apply(scrollId);
scrollHits = nextPage.iterator();
scrollId = nextPage.getScrollId();
continueScroll = scrollHits.hasNext();
}
return currentHits.hasNext();
return scrollHits.hasNext();
}
@Override
public T next() {
if (hasNext()) {
return currentHits.next();
return scrollHits.next();
}
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove");
throw new UnsupportedOperationException();
}
};
}
// utility constructor
private StreamQueries() {}
private StreamQueries() {
}
}
@@ -19,6 +19,7 @@ import java.util.Arrays;
import java.util.List;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.annotations.Parent;
import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.mapping.Association;
@@ -77,13 +78,15 @@ public class SimpleElasticsearchPersistentProperty extends
@Nullable
private String getAnnotatedFieldName() {
if (isAnnotationPresent(Field.class)) {
String name = null;
String name = findAnnotation(Field.class).name();
return StringUtils.hasText(name) ? name : null;
if (isAnnotationPresent(MultiField.class)) {
name = findAnnotation(MultiField.class).mainField().name();
} else if (isAnnotationPresent(Field.class)) {
name = findAnnotation(Field.class).name();
}
return null;
return StringUtils.hasText(name) ? name : null;
}
/*
@@ -15,10 +15,13 @@
*/
package org.springframework.data.elasticsearch.core.query;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.elasticsearch.core.geo.GeoBox;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
@@ -26,6 +29,8 @@ import org.springframework.data.geo.Box;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Criteria is the central class when constructing queries. It follows more or less a fluent API style, which allows to
@@ -39,13 +44,9 @@ public class Criteria {
@Override
public String toString() {
return "Criteria{" +
"field=" + field.getName() +
", boost=" + boost +
", negating=" + negating +
", queryCriteria=" + ObjectUtils.nullSafeToString(queryCriteria) +
", filterCriteria=" + ObjectUtils.nullSafeToString(filterCriteria) +
'}';
return "Criteria{" + "field=" + field.getName() + ", boost=" + boost + ", negating=" + negating + ", queryCriteria="
+ ObjectUtils.nullSafeToString(queryCriteria) + ", filterCriteria="
+ ObjectUtils.nullSafeToString(filterCriteria) + '}';
}
public static final String WILDCARD = "*";
@@ -64,8 +65,7 @@ public class Criteria {
private Set<CriteriaEntry> filterCriteria = new LinkedHashSet<>();
public Criteria() {
}
public Criteria() {}
/**
* Creates a new Criteria with provided field name
@@ -305,7 +305,7 @@ public class Criteria {
throw new InvalidDataAccessApiUsageException("Range [* TO *] is not allowed");
}
queryCriteria.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[]{lowerBound, upperBound}));
queryCriteria.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound }));
return this;
}
@@ -376,11 +376,6 @@ public class Criteria {
}
private List<Object> toCollection(Object... values) {
if (values.length == 0 || (values.length > 1 && values[1] instanceof Collection)) {
throw new InvalidDataAccessApiUsageException("At least one element "
+ (values.length > 0 ? ("of argument of type " + values[1].getClass().getName()) : "")
+ " has to be present.");
}
return Arrays.asList(values);
}
@@ -398,15 +393,14 @@ public class Criteria {
* Creates new CriteriaEntry for {@code location WITHIN distance}
*
* @param location {@link org.springframework.data.elasticsearch.core.geo.GeoPoint} center coordinates
* @param distance {@link String} radius as a string (e.g. : '100km').
* Distance unit :
* either mi/miles or km can be set
* @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be
* set
* @return Criteria the chaind criteria with the new 'within' criteria included.
*/
public Criteria within(GeoPoint location, String distance) {
Assert.notNull(location, "Location value for near criteria must not be null");
Assert.notNull(location, "Distance value for near criteria must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{location, distance}));
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
return this;
}
@@ -414,56 +408,54 @@ public class Criteria {
* Creates new CriteriaEntry for {@code location WITHIN distance}
*
* @param location {@link org.springframework.data.geo.Point} center coordinates
* @param distance {@link org.springframework.data.geo.Distance} radius
* .
* @param distance {@link org.springframework.data.geo.Distance} radius .
* @return Criteria the chaind criteria with the new 'within' criteria included.
*/
public Criteria within(Point location, Distance distance) {
Assert.notNull(location, "Location value for near criteria must not be null");
Assert.notNull(location, "Distance value for near criteria must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{location, distance}));
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
return this;
}
/**
* Creates new CriteriaEntry for {@code geoLocation WITHIN distance}
*
* @param geoLocation {@link String} center point
* supported formats:
* lat on = > "41.2,45.1",
* geohash = > "asd9as0d"
* @param distance {@link String} radius as a string (e.g. : '100km').
* Distance unit :
* either mi/miles or km can be set
* @param geoLocation {@link String} center point supported formats: lat on = > "41.2,45.1", geohash = > "asd9as0d"
* @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be
* set
* @return
*/
public Criteria within(String geoLocation, String distance) {
Assert.isTrue(!StringUtils.isEmpty(geoLocation), "geoLocation value must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{geoLocation, distance}));
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance }));
return this;
}
/**
* Creates new CriteriaEntry for {@code location GeoBox bounding box}
*
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner)
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner +
* right bottom corner)
* @return Criteria the chaind criteria with the new 'boundingBox' criteria included.
*/
public Criteria boundedBy(GeoBox boundingBox) {
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox}));
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox }));
return this;
}
/**
* Creates new CriteriaEntry for {@code location Box bounding box}
*
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner)
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner +
* right bottom corner)
* @return Criteria the chaind criteria with the new 'boundingBox' criteria included.
*/
public Criteria boundedBy(Box boundingBox) {
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox.getFirst(), boundingBox.getSecond()}));
filterCriteria
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox.getFirst(), boundingBox.getSecond() }));
return this;
}
@@ -477,7 +469,7 @@ public class Criteria {
public Criteria boundedBy(String topLeftGeohash, String bottomRightGeohash) {
Assert.isTrue(!StringUtils.isEmpty(topLeftGeohash), "topLeftGeohash must not be empty");
Assert.isTrue(!StringUtils.isEmpty(bottomRightGeohash), "bottomRightGeohash must not be empty");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{topLeftGeohash, bottomRightGeohash}));
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash }));
return this;
}
@@ -491,14 +483,15 @@ public class Criteria {
public Criteria boundedBy(GeoPoint topLeftPoint, GeoPoint bottomRightPoint) {
Assert.notNull(topLeftPoint, "topLeftPoint must not be null");
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{topLeftPoint, bottomRightPoint}));
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint }));
return this;
}
public Criteria boundedBy(Point topLeftPoint, Point bottomRightPoint) {
Assert.notNull(topLeftPoint, "topLeftPoint must not be null");
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint)}));
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX,
new Object[] { GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint) }));
return this;
}
@@ -611,10 +604,7 @@ public class Criteria {
@Override
public String toString() {
return "CriteriaEntry{" +
"key=" + key +
", value=" + value +
'}';
return "CriteriaEntry{" + "key=" + key + ", value=" + value + '}';
}
}
}
@@ -155,7 +155,13 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
Assert.notNull(ids, "ids can't be null.");
SearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build();
List<String> stringIds = stringIdsRepresentation(ids);
if (stringIds.isEmpty()) {
return Collections.emptyList();
}
SearchQuery query = new NativeSearchQueryBuilder().withIds(stringIds).build();
return elasticsearchOperations.multiGet(query, getEntityClass());
}
+393
View File
@@ -1,6 +1,372 @@
Spring Data Elasticsearch Changelog
===================================
Changes in version 3.2.11.RELEASE (2020-10-28)
----------------------------------------------
* DATAES-961 - Upgrade to Elasticsearch 6.8.13.
* DATAES-937 - Repository queries with IN filters fail with empty input list.
* DATAES-925 - Release 3.2.11 (Moore SR11).
Changes in version 3.1.21.RELEASE (2020-10-28)
----------------------------------------------
* DATAES-958 - Release 3.1.21 (Lovelace SR21).
Changes in version 4.1.0-RC2 (2020-10-14)
-----------------------------------------
* DATAES-949 - dependency cleanup.
* DATAES-947 - Adopt to API changes in Project Reactor.
* DATAES-945 - Compilation error on JDK11+.
* DATAES-944 - Simplify logging setup in test environment.
* DATAES-943 - Add missing mapping parameters.
* DATAES-940 - Update to Elasticsearch 7.9.2.
* DATAES-937 - Repository queries with IN filters fail with empty input list.
* DATAES-936 - Take id property from the source when deserializing an entity.
* DATAES-935 - Setup integration tests separate from unit tests.
* DATAES-934 - Add a Query taking method to ElasticsearchRepository.
* DATAES-933 - Fix typo in javaDoc.
* DATAES-932 - GeoPoint - Point conversion is wrong.
* DATAES-930 - Add support for geo_shape type entity properties.
* DATAES-929 - Support geo_shape field type field type.
* DATAES-927 - Release 4.1 RC2 (2020.0.0).
* DATAES-921 - Investigate WebClient.retrieve() instead of using WebClient.exchange().
Changes in version 4.1.0-RC1 (2020-09-16)
-----------------------------------------
* DATAES-924 - Conversion of properties of collections of Temporal values fails.
* DATAES-923 - Upgrade to Elasticsearch 7.9.1.
* DATAES-922 - Move off Sink.emitXXX methods.
* DATAES-920 - Add parameter to @Field annotation to store null values.
* DATAES-919 - Fix error messages in test output.
* DATAES-914 - Use Testcontainers.
* DATAES-913 - Minor optimization on collection-returning derived queries.
* DATAES-912 - Derived Query with "In" Keyword does not work on Text field.
* DATAES-911 - Add documentation for automatic index creation.
* DATAES-910 - Upgrade to Elasticsearch 7.9.0.
* DATAES-909 - Add singular update() methods to ReactiveDocumentOperations.
* DATAES-908 - Fill version on an indexed entity.
* DATAES-907 - Track Total Hits not working when set to false.
* DATAES-904 - Release 4.1 RC1 (2020.0.0).
* DATAES-902 - Update to Elasticsearch 7.8.1.
* DATAES-898 - Add join-type relevant parts to reactive calls.
* DATAES-895 - Criteria.OperationKey.NEAR is not used anywhere.
* DATAES-854 - Add support for rank_feature datatype.
* DATAES-706 - CriteriaQueryProcessor must handle nested Criteria definitions.
Changes in version 4.0.4.RELEASE (2020-09-16)
---------------------------------------------
* DATAES-924 - Conversion of properties of collections of Temporal values fails.
* DATAES-912 - Derived Query with "In" Keyword does not work on Text field.
* DATAES-905 - Release 4.0.4 (Neumann SR4).
Changes in version 3.2.10.RELEASE (2020-09-16)
----------------------------------------------
* DATAES-903 - Update to Elasticsearch 6.8.12.
* DATAES-892 - Fix ElasticsearchEntityMapper recursive descent when reading Map objects.
* DATAES-888 - Release 3.2.10 (Moore SR10).
Changes in version 3.1.20.RELEASE (2020-09-16)
----------------------------------------------
* DATAES-887 - Release 3.1.20 (Lovelace SR20).
Changes in version 4.0.3.RELEASE (2020-08-12)
---------------------------------------------
* DATAES-897 - Add documentation for Highlight annotation.
* DATAES-896 - Use mainField property of @MultiField annotation instead of additional @Field annotation.
* DATAES-891 - Returning a Stream from a Query annotated repository method crashes.
* DATAES-890 - Release 4.0.3 (Neumann SR3).
Changes in version 4.1.0-M2 (2020-08-12)
----------------------------------------
* DATAES-901 - Operations deleting an entity should use a routing deducted from the entity.
* DATAES-899 - Add documentation for join-type.
* DATAES-897 - Add documentation for Highlight annotation.
* DATAES-896 - Use mainField property of @MultiField annotation instead of additional @Field annotation.
* DATAES-894 - Adapt to changes in Reactor.
* DATAES-893 - Adopt to changed module layout of Reactor Netty.
* DATAES-891 - Returning a Stream from a Query annotated repository method crashes.
* DATAES-886 - Complete reactive auditing.
* DATAES-883 - Fix log level on resource load error.
* DATAES-878 - Wrong value for TermVector(woth_positions_offsets).
* DATAES-877 - Update test logging dependency.
* DATAES-876 - Add seqno and primary term to entity on initial save.
* DATAES-875 - MappingElasticsearchConverter.updateQuery not called at all places.
* DATAES-874 - Deprecate parent-id related methods and fields.
* DATAES-872 - Release 4.1 M2 (2020.0.0).
* DATAES-869 - Update to Elasticsearch 7.8.
* DATAES-864 - Rework alias management.
* DATAES-842 - Documentation fixes.
* DATAES-612 - Add support for index templates.
* DATAES-433 - Replace parent-child mappings to join field.
* DATAES-321 - Support time base rolling indices.
* DATAES-244 - Support alias renaming.
* DATAES-233 - Support for rolling index strategy.
* DATAES-207 - Allow fetching indices by alias.
* DATAES-192 - Define alias for document.
* DATAES-150 - mapping are not created when entity is saved in new dynamic name index (spel).
Changes in version 4.0.2.RELEASE (2020-07-22)
---------------------------------------------
* DATAES-883 - Fix log level on resource load error.
* DATAES-878 - Wrong value for TermVector(woth_positions_offsets).
* DATAES-865 - Fix MappingElasticsearchConverter writing an Object property containing a Map.
* DATAES-863 - Improve server error response handling.
* DATAES-862 - Release 4.0.2 (Neumann SR2).
Changes in version 3.2.9.RELEASE (2020-07-22)
---------------------------------------------
* DATAES-861 - Release 3.2.9 (Moore SR9).
Changes in version 3.1.19.RELEASE (2020-07-22)
----------------------------------------------
* DATAES-860 - Release 3.1.19 (Lovelace SR19).
Changes in version 4.1.0-M1 (2020-06-25)
----------------------------------------
* DATAES-870 - Workaround for reactor-netty error.
* DATAES-868 - Upgrade to Netty 4.1.50.Final.
* DATAES-867 - Adopt to changes in Reactor Netty 1.0.
* DATAES-866 - Implement suggest search in reactive client.
* DATAES-865 - Fix MappingElasticsearchConverter writing an Object property containing a Map.
* DATAES-863 - Improve server error response handling.
* DATAES-859 - Don't use randomNumeric() in tests.
* DATAES-858 - Use standard Spring code of conduct.
* DATAES-857 - Registered simple types are not read from list.
* DATAES-853 - Cleanup tests that do not delete test indices.
* DATAES-852 - Upgrade to Elasticsearch 7.7.1.
* DATAES-850 - Add warning and documentation for missing TemporalAccessor configuration.
* DATAES-848 - Add the name of the index to SearchHit.
* DATAES-847 - Add missing DateFormat values.
* DATAES-845 - MappingElasticsearchConverter crashes when writing lists containing null values.
* DATAES-844 - Improve TOC formatting for migration guides.
* DATAES-841 - Remove deprecated type mappings code.
* DATAES-840 - Consolidate index name SpEL resolution.
* DATAES-839 - ReactiveElasticsearchTemplate should use RequestFactory.
* DATAES-838 - Update to Elasticsearch 7.7.0.
* DATAES-836 - Fix typo in Javadocs.
* DATAES-835 - Fix code sample in documentation for scroll API.
* DATAES-832 - findAllById repository method returns iterable with null elements for not found ids.
* DATAES-831 - SearchOperations.searchForStream does not use requested maxResults.
* DATAES-829 - Deprecate AbstractElasticsearchRepository and cleanup SimpleElasticsearchRepository.
* DATAES-828 - Fields of type date need to have a format defined.
* DATAES-827 - Repositories should not try to create an index when it already exists.
* DATAES-826 - Add method to IndexOperations to write an index mapping from a entity class.
* DATAES-825 - Update readme to use latest spring.io docs.
* DATAES-824 - Release 4.1 M1 (2020.0.0).
* DATAES-678 - Introduce ReactiveIndexOperations.
* DATAES-263 - Inner Hits support.
Changes in version 4.0.1.RELEASE (2020-06-10)
---------------------------------------------
* DATAES-857 - Registered simple types are not read from list.
* DATAES-850 - Add warning and documentation for missing TemporalAccessor configuration.
* DATAES-845 - MappingElasticsearchConverter crashes when writing lists containing null values.
* DATAES-844 - Improve TOC formatting for migration guides.
* DATAES-839 - ReactiveElasticsearchTemplate should use RequestFactory.
* DATAES-835 - Fix code sample in documentation for scroll API.
* DATAES-832 - findAllById repository method returns iterable with null elements for not found ids.
* DATAES-831 - SearchOperations.searchForStream does not use requested maxResults.
* DATAES-828 - Fields of type date need to have a format defined.
* DATAES-827 - Repositories should not try to create an index when it already exists.
* DATAES-823 - Release 4.0.1 (Neumann SR1).
Changes in version 3.2.8.RELEASE (2020-06-10)
---------------------------------------------
* DATAES-851 - Upgrade to Elasticsearch 6.8.10.
* DATAES-837 - Update to Elasticsearch 6.8.9.
* DATAES-821 - Fix code for adding an alias.
* DATAES-811 - Remove Travis CI.
* DATAES-807 - Release 3.2.8 (Moore SR8).
* DATAES-776 - Adapt RestClients class to change in InetSocketAddress class in JDK14.
* DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses.
Changes in version 3.1.18.RELEASE (2020-06-10)
----------------------------------------------
* DATAES-811 - Remove Travis CI.
* DATAES-806 - Release 3.1.18 (Lovelace SR18).
Changes in version 4.0.0.RC2 (2020-04-28)
-----------------------------------------
* DATAES-803 - Move count request setup from reactive template to reactive client.
* DATAES-802 - Update documentation for using scroll API with repository methods.
* DATAES-801 - Implement callback to enable adding custom headers in the REST HTTP request.
* DATAES-800 - De-Lombok production code.
* DATAES-797 - Fix MappingElasticsearchConverter recursive descent when reading Map objetcsa.
* DATAES-795 - Fix MappingElasticsearchConverter conversion from Document into Map<String, Object>.
* DATAES-794 - MappingBuilder must not write empty mapping properties.
* DATAES-792 - Add java.util.Date to the supported types for Field annonation date times.
* DATAES-791 - DocumentOperations.multiGet() implementations must return null values for not found entities.
* DATAES-790 - Deprecate noRefresh repository method.
* DATAES-789 - Make ElasticsearchRestTemplate.ClientCallback public.
* DATAES-788 - Add missing path mapping to completion context.
* DATAES-787 - Use JDK 14 for Java.NEXT CI testing.
* DATAES-786 - Move the creation of SearchHit(s) from ElasticsearchConverter closer to ElasticsearchTemplate.
* DATAES-785 - Various entity callbacks implementation improvements.
* DATAES-784 - MappingBuilder should use @Field annotation with custom value objects.
* DATAES-782 - Make underlying TransportClient accessible.
* DATAES-781 - Upgrade to Elasticsearch 7.6.2.
* DATAES-778 - Fix SSL setup in the reactive client.
* DATAES-777 - SearchHitsSupport must preserve pageable when unwrapping to AggregatedPage.
* DATAES-776 - Adapt RestClients class to change in InetSocketAddress class in JDK14.
* DATAES-775 - Fix test runner setup.
* DATAES-774 - Release 4.0 RC2 (Neumann).
* DATAES-773 - Add search-as-you-type field support to index mappings.
* DATAES-772 - Add after-convert entity callbacks support.
* DATAES-567 - Unable to read aggregations via Reactive*Operations.
Changes in version 3.2.7.RELEASE (2020-04-28)
---------------------------------------------
* DATAES-780 - Upgrade 3.2.x to Elasticsearch 6.8.8.
* DATAES-778 - Fix SSL setup in the reactive client.
* DATAES-770 - Release 3.2.7 (Moore SR7).
Changes in version 3.1.17.RELEASE (2020-04-28)
----------------------------------------------
* DATAES-793 - Upgrade to Elasticsearch 6.2.4.
* DATAES-755 - Release 3.1.17 (Lovelace SR17).
Changes in version 4.0.0.RC1 (2020-03-31)
-----------------------------------------
* DATAES-771 - Add after-save entity callbacks support.
* DATAES-768 - Add missing query parameters for an UpdateQuery.
* DATAES-766 - Replace CloseableIterator with SearchHitsIterator in stream operations.
* DATAES-765 - Pageable.unpaged() is not used to build a query returning all documents.
* DATAES-763 - Allow map properties in entity with null values.
* DATAES-762 - Release 4.0 RC1 (Neumann).
* DATAES-751 - Introduce ClientCallbackfor the rest client.
* DATAES-653 - Make it easier to use a custom request converter when extending DefaultReactiveElasticsearchClient.
* DATAES-435 - Report version mismatch if used with older ElasticSearch version.
* DATAES-382 - Add Exception translation for Elasticsearch errors.
* DATAES-68 - Add support for auditing annotations.
Changes in version 3.2.6.RELEASE (2020-03-25)
---------------------------------------------
* DATAES-769 - Upgrade to Elasticsearch 6.8.7.
* DATAES-765 - Pageable.unpaged() is not used to build a query returning all documents.
* DATAES-764 - StreamQueries#streamResults does not clear scroll context when finished.
* DATAES-763 - Allow map properties in entity with null values.
* DATAES-758 - fix documentation for @Query annotation.
* DATAES-756 - Release 3.2.6 (Moore SR6).
Changes in version 4.0.0.M4 (2020-03-11)
----------------------------------------
* DATAES-759 - Update to Elasticsearch 7.6.1.
* DATAES-758 - fix documentation for @Query annotation.
* DATAES-754 - Completion field deserialization is failing due to class cast error.
* DATAES-753 - Reactive Elasticsearch repository: Bulk update fails on empty entity list.
* DATAES-749 - Introduce SearchPage as return type for repository methods.
* DATAES-747 - ElasticsearchConfigurationSupport does not set customConversions into the MappingElasticsearchConverter.
* DATAES-746 - Add store converters to convert binary data to base64 encoded strings.
* DATAES-745 - Consolidate Operations API.
* DATAES-744 - Release 4.0 M4 (Neumann).
* DATAES-741 - Tests fail due to Elasticsearch cluster 'blocks' on nearly-full file-systems.
* DATAES-282 - Remove all low-level reflection based field inspection from MappingBuilder in favor of PersistentProperty inspections.
Changes in version 3.2.5.RELEASE (2020-02-26)
---------------------------------------------
* DATAES-752 - Upgrade to Elasticsearch 6.8.6.
* DATAES-741 - Tests fail due to Elasticsearch cluster 'blocks' on nearly-full file-systems.
* DATAES-730 - Release 3.2.5 (Moore SR5).
* DATAES-214 - ElasticsearchTemplate's prepareSearch(Query query) method should use getOffset().
Changes in version 3.1.16.RELEASE (2020-02-26)
----------------------------------------------
* DATAES-729 - Release 3.1.16 (Lovelace SR16).
Changes in version 4.0.0.M3 (2020-02-12)
----------------------------------------
* DATAES-743 - Revert geo converters to back to store converters.
* DATAES-740 - Adapt to spring-data-commons changes.
* DATAES-739 - Introduce nullable annotations for API validation.
* DATAES-738 - Add entity related save methods to DocumentOperations.
* DATAES-735 - Update to Elasticsearch 7.5.2.
* DATAES-734 - Add Sort implementation that allows geo distance sorts.
* DATAES-732 - Release 4.0 M3 (Neumann).
* DATAES-449 - Pass route parameter to created search request.
Changes in version 4.0.0.M2 (2020-01-17)
----------------------------------------
* DATAES-731 - Release 4.0 M2 (Neumann).
Changes in version 4.0.0.M1 (2020-01-16)
----------------------------------------
* DATAES-727 - Use track_total_hits parameter for count queries.
* DATAES-725 - Update copyright years to 2020.
* DATAES-724 - Provide IndexOperations bean.
* DATAES-723 - Cleanup ElasticsearchRepository interface.
* DATAES-722 - Return total count relation in the SearchHits object.
* DATAES-721 - Deprecation and Warnings cleanup.
* DATAES-720 - SimpleReactiveElasticsearchRepository findAll() returns only 10 elements.
* DATAES-719 - Add customization hook for reactive WebClient.
* DATAES-718 - Deprecate @Score and scoreProperty.
* DATAES-717 - Enable Repositories to return a SearchHits instance instead of a list.
* DATAES-716 - Add Value mapping to the ElasticsearchMappingConverter.
* DATAES-715 - Highlight results should be returned in the SearchHits.
* DATAES-714 - Sort results should be returned in the SearchHits.
* DATAES-713 - Transfer returned aggregations from the AggregatedPage to the SearchHits.
* DATAES-711 - Update to Elasticsearch 7.5.
* DATAES-709 - Add parameter to include default settings on setting request.
* DATAES-702 - Travis CI builds currently broken.
* DATAES-701 - Enable proxy support for the reactive rest template.
* DATAES-700 - Enable proxy support for RestClient.
* DATAES-697 - Query refactoring cleanup.
* DATAES-693 - Support for source fetching in update operations.
* DATAES-690 - Enable builds on JDK 11+.
* DATAES-688 - Remove unneeded SearchQuery subinterface.
* DATAES-684 - Implement Bulk Request for Reactive.
* DATAES-680 - ReactiveElasticsearchTemplate should use the count API.
* DATAES-677 - Update to Elasticsearch 7.4.1.
* DATAES-676 - fix documentation to reflect the changes in API restructuring.
* DATAES-675 - migrate tests to JUnit 5.
* DATAES-673 - Create a Ssl Rest Client using SslContext and HostnameVerifier.
* DATAES-672 - Introduce SearchHit to enrich an Entity type.
* DATAES-671 - Missing indicesOptions support for scrolling queries.
* DATAES-670 - fix version compatibility matrix in documentation.
* DATAES-666 - Rebase branch 4.0.x onto master and merge it.
* DATAES-665 - Javadoc not deployed.
* DATAES-663 - Release 4.0 M1 (Neumann).
* DATAES-661 - Support track_total_hits request parameter.
* DATAES-659 - Move MappingElasticsearchConverter to correct package.
* DATAES-658 - Update 4.0.x to ES 7.3.2.
* DATAES-654 - Add Junit 5 support.
* DATAES-651 - Fix regression from escaping.
* DATAES-650 - Add support for pathPrefix to ClientConfiguration.
* DATAES-647 - In and NotIn uses should instead of terms-query.
* DATAES-639 - Add ignore_above mapping parameter support.
* DATAES-638 - Remove redundant public modifiers in @MultiField.
* DATAES-637 - Change branch 4.0. to use Elasticsearch 7.3.
* DATAES-635 - Create branch 4.0.x and integrate the changes from the existing 4.x branch.
* DATAES-634 - Rearrange methods in Template API.
* DATAES-633 - Introduce value object to capture index type/index name.
* DATAES-632 - Use single Query type in Template API methods.
* DATAES-631 - Consolidate query objects.
Changes in version 3.2.4.RELEASE (2020-01-15)
---------------------------------------------
* DATAES-725 - Update copyright years to 2020.
@@ -941,3 +1307,30 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07)
+8 -1
View File
@@ -1,4 +1,4 @@
Spring Data Elasticsearch 3.2.4
Spring Data Elasticsearch 3.2.11 (Moore SR11)
Copyright (c) [2013-2019] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -10,3 +10,10 @@ code for the these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.
@@ -551,7 +551,7 @@ public class ReactiveElasticsearchClientTests {
assertThat(syncClient.indices().exists(new GetIndexRequest().indices(INDEX_I), RequestOptions.DEFAULT)).isFalse();
}
@Test // DATAES-569
@Test // DATAES-569, DATAES-767
public void deleteNonExistingIndexErrors() {
client.indices().deleteIndex(request -> request.indices(INDEX_I)) //
@@ -569,7 +569,7 @@ public class ReactiveElasticsearchClientTests {
.verifyComplete();
}
@Test // DATAES-569
@Test // DATAES-569, DATAES-767
public void openNonExistingIndex() {
client.indices().openIndex(request -> request.indices(INDEX_I)) //
@@ -587,7 +587,7 @@ public class ReactiveElasticsearchClientTests {
.verifyComplete();
}
@Test // DATAES-569
@Test // DATAES-569, DATAES-767
public void closeNonExistingIndex() {
client.indices().closeIndex(request -> request.indices(INDEX_I)) //
@@ -605,7 +605,7 @@ public class ReactiveElasticsearchClientTests {
.verifyComplete();
}
@Test // DATAES-569
@Test // DATAES-569, DATAES-767
public void refreshNonExistingIndex() {
client.indices().refreshIndex(request -> request.indices(INDEX_I)) //
@@ -626,7 +626,7 @@ public class ReactiveElasticsearchClientTests {
.verifyComplete();
}
@Test // DATAES-569
@Test // DATAES-569, DATAES-767
public void updateMappingNonExistingIndex() {
Map<String, Object> jsonMap = Collections.singletonMap("properties",
@@ -647,7 +647,7 @@ public class ReactiveElasticsearchClientTests {
.verifyComplete();
}
@Test // DATAES-569
@Test // DATAES-569, DATAES-767
public void flushNonExistingIndex() {
client.indices().flushIndex(request -> request.indices(INDEX_I)) //
@@ -456,7 +456,7 @@ public class ReactiveElasticsearchClientUnitTests {
.verifyComplete();
}
@Test // DATAES-488
@Test // DATAES-488, DATAES-767
public void updateShouldEmitErrorWhenNotFound() {
hostProvider.when(HOST) //
@@ -531,6 +531,32 @@ public class ElasticsearchEntityMapperUnitTests {
assertThat(target.address).isEqualTo(bigBunsCafe);
}
@Test // DATAES-892
public void readGenericListWithMaps() {
Map<String, Object> simpleMap = new HashMap<>();
simpleMap.put("int", 1);
List<Map<String, Object>> listWithSimpleMap = new ArrayList<>();
listWithSimpleMap.add(simpleMap);
Map<String, List<Map<String, Object>>> mapWithSimpleList = new HashMap<>();
mapWithSimpleList.put("someKey", listWithSimpleMap);
Map<String, Object> document = new LinkedHashMap<>();
document.put("schemaLessObject", mapWithSimpleList);
SchemaLessObjectWrapper wrapper = entityMapper.read(SchemaLessObjectWrapper.class, document);
assertThat(wrapper.getSchemaLessObject()).isEqualTo(mapWithSimpleList);
}
@Data
@NoArgsConstructor
@AllArgsConstructor
static class SchemaLessObjectWrapper {
private Map<String, Object> schemaLessObject;
}
private String pointTemplate(String name, Point point) {
return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY());
}
@@ -394,13 +394,31 @@ public class MappingBuilderTests extends MappingContextBaseTests {
assertEquals(expected, mapping, false);
}
@Test // DATAES-568
@Test // DATAES-568, DATAES-896
public void shouldUseFieldNameOnMultiField() throws IOException, JSONException {
// given
String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true},"
+ "\"multifield-property\":{\"store\":false,\"type\":\"text\",\"analyzer\":\"whitespace\",\"fields\":{\"prefix\":{\"store\":false,\"type\":\"text\",\"analyzer\":\"stop\",\"search_analyzer\":\"standard\"}}}"
+ "}}}";
String expected = "{\n" + //
" \"fieldname-type\": {\n" + //
" \"properties\": {\n" + //
" \"id-property\": {\n" + //
" \"type\": \"keyword\",\n" + //
" \"index\": true\n" + //
" },\n" + //
" \"main-field\": {\n" + //
" \"type\": \"text\",\n" + //
" \"analyzer\": \"whitespace\",\n" + //
" \"fields\": {\n" + //
" \"suff-ix\": {\n" + //
" \"type\": \"text\",\n" + //
" \"analyzer\": \"stop\",\n" + //
" \"search_analyzer\": \"standard\"\n" + //
" }\n" + //
" }\n" + //
" }\n" + //
" }\n" + //
" }\n" + //
"}\n"; //
// when
String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.MultiFieldEntity.class);
@@ -470,9 +488,9 @@ public class MappingBuilderTests extends MappingContextBaseTests {
@Id @Field("id-property") private String id;
@Field("multifield-property") //
@MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"), otherFields = {
@InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard") }) //
private String description;
@MultiField(mainField = @Field(name = "main-field", type = FieldType.Text, analyzer = "whitespace"),
otherFields = { @InnerField(suffix = "suff-ix", type = FieldType.Text, analyzer = "stop",
searchAnalyzer = "standard") }) private String description;
}
}
@@ -203,12 +203,12 @@ public class ReactiveElasticsearchTemplateTests {
template.save(null);
}
@Test // DATAES-519
public void findByIdShouldCompleteWhenIndexDoesNotExist() {
@Test // DATAES-519, DATAES-767
public void getByIdShouldCompleteWhenIndexDoesNotExist() {
template.findById("foo", SampleEntity.class, "no-such-index") //
.as(StepVerifier::create) //
.verifyComplete();
.expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-504
@@ -312,12 +312,12 @@ public class ReactiveElasticsearchTemplateTests {
.verifyComplete();
}
@Test // DATAES-519
public void findShouldCompleteWhenIndexDoesNotExist() {
@Test // DATAES-519, DATAES-767
public void searchShouldCompleteWhenIndexDoesNotExist() {
template.find(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, "no-such-index") //
.as(StepVerifier::create) //
.verifyComplete();
.expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-504
@@ -410,7 +410,7 @@ public class ReactiveElasticsearchTemplateTests {
.verifyComplete();
}
@Test // DATAES-595
@Test // DATAES-595, DATAES-767
public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGivenCriteria() {
SampleEntity sampleEntity1 = randomEntity("test message");
@@ -480,13 +480,12 @@ public class ReactiveElasticsearchTemplateTests {
.verifyComplete();
}
@Test // DATAES-519
@Test // DATAES-519, DATAES-767
public void countShouldReturnZeroWhenIndexDoesNotExist() {
template.count(SampleEntity.class) //
.as(StepVerifier::create) //
.expectNext(0L) //
.verifyComplete();
.expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-504
@@ -513,12 +512,12 @@ public class ReactiveElasticsearchTemplateTests {
.verifyComplete();
}
@Test // DATAES-519
public void deleteByIdShouldCompleteWhenIndexDoesNotExist() {
@Test // DATAES-519, DATAES-767
public void deleteShouldErrorWhenIndexDoesNotExist() {
template.deleteById("does-not-exists", SampleEntity.class, "no-such-index") //
.as(StepVerifier::create)//
.verifyComplete();
.expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-504
@@ -0,0 +1,77 @@
/*
* Copyright 2020 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
*
* https://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;
import static org.assertj.core.api.Assertions.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.util.CloseableIterator;
import org.springframework.lang.Nullable;
/**
* @author Sascha Woo
*/
public class StreamQueriesTest {
@Test // DATAES-764
public void shouldCallClearScrollOnIteratorClose() {
// given
List<String> results = new ArrayList<>();
results.add("one");
ScrolledPage<String> page = new ScrolledPageImpl("1234", results);
AtomicBoolean clearScrollCalled = new AtomicBoolean(false);
// when
CloseableIterator<String> closeableIterator = StreamQueries.streamResults( //
page, //
scrollId -> new ScrolledPageImpl(scrollId, Collections.emptyList()), //
scrollId -> clearScrollCalled.set(true));
while (closeableIterator.hasNext()) {
closeableIterator.next();
}
closeableIterator.close();
// then
assertThat(clearScrollCalled).isTrue();
}
private static class ScrolledPageImpl extends PageImpl<String> implements ScrolledPage<String> {
private String scrollId;
public ScrolledPageImpl(String scrollId, List<String> content) {
super(content);
this.scrollId = scrollId;
}
@Override
@Nullable
public String getScrollId() {
return scrollId;
}
}
}
@@ -19,8 +19,12 @@ import static org.assertj.core.api.Assertions.*;
import org.junit.Test;
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;
import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.mapping.MappingException;
import org.springframework.lang.Nullable;
/**
* Unit tests for {@link SimpleElasticsearchPersistentProperty}.
@@ -62,6 +66,16 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
assertThat(persistentProperty.getFieldName()).isEqualTo("by-value");
}
@Test // DATAES-896
public void shouldUseNameFromMultiFieldMainField() {
SimpleElasticsearchPersistentEntity<?> persistentEntity = context
.getRequiredPersistentEntity(MultiFieldProperty.class);
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getPersistentProperty("mainfieldProperty");
assertThat(persistentProperty).isNotNull();
assertThat(persistentProperty.getFieldName()).isEqualTo("mainfield");
}
static class InvalidScoreProperty {
@Score String scoreProperty;
}
@@ -73,4 +87,9 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
static class FieldValueProperty {
@Field(value = "by-value") String fieldProperty;
}
static class MultiFieldProperty {
@Nullable @MultiField(mainField = @Field("mainfield"),
otherFields = { @InnerField(suffix = "suff", type = FieldType.Keyword) }) String mainfieldProperty;
}
}
@@ -23,6 +23,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -61,15 +62,15 @@ abstract class QueryKeywordsTests {
IndexInitializer.init(elasticsearchTemplate, Product.class);
Product product1 = Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false)
Product product1 = Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false)
.sortName("sort5").build();
Product product2 = Product.builder().id("2").name("Sugar").text("Cane sugar").price(1.2f).available(true)
Product product2 = Product.builder().id("2").name("Sugar").text("Cane sugar").price(1.2f).available(true)
.sortName("sort4").build();
Product product3 = Product.builder().id("3").name("Sugar").text("Beet sugar").price(1.1f).available(true)
Product product3 = Product.builder().id("3").name("Sugar").text("Beet sugar").price(1.1f).available(true)
.sortName("sort3").build();
Product product4 = Product.builder().id("4").name("Salt").text("Rock salt").price(1.9f).available(true)
Product product4 = Product.builder().id("4").name("Salt").text("Rock salt").price(1.9f).available(true)
.sortName("sort2").build();
Product product5 = Product.builder().id("5").name("Salt").text("Sea salt").price(2.1f).available(false)
Product product5 = Product.builder().id("5").name("Salt").text("Sea salt").price(2.1f).available(false)
.sortName("sort1").build();
repository.saveAll(Arrays.asList(product1, product2, product3, product4, product5));
@@ -165,7 +166,7 @@ abstract class QueryKeywordsTests {
@Test // DATAES-615
public void shouldSupportSortOnStandardFieldWithCriteria() {
List<String> sortedIds = repository.findAllByNameOrderByText("Salt").stream() //
List<String> sortedIds = repository.findAllByNameOrderByText("Salt").stream() //
.map(it -> it.id).collect(Collectors.toList());
assertThat(sortedIds).containsExactly("4", "5");
@@ -174,7 +175,7 @@ abstract class QueryKeywordsTests {
@Test // DATAES-615
public void shouldSupportSortOnFieldWithCustomFieldNameWithCriteria() {
List<String> sortedIds = repository.findAllByNameOrderBySortName("Sugar").stream() //
List<String> sortedIds = repository.findAllByNameOrderBySortName("Sugar").stream() //
.map(it -> it.id).collect(Collectors.toList());
assertThat(sortedIds).containsExactly("3", "2", "1");
@@ -182,7 +183,7 @@ abstract class QueryKeywordsTests {
@Test // DATAES-615
public void shouldSupportSortOnStandardFieldWithoutCriteria() {
List<String> sortedIds = repository.findAllByOrderByText().stream() //
List<String> sortedIds = repository.findAllByOrderByText().stream() //
.map(it -> it.text).collect(Collectors.toList());
assertThat(sortedIds).containsExactly("Beet sugar", "Cane sugar", "Cane sugar", "Rock salt", "Sea salt");
@@ -191,12 +192,28 @@ abstract class QueryKeywordsTests {
@Test // DATAES-615
public void shouldSupportSortOnFieldWithCustomFieldNameWithoutCriteria() {
List<String> sortedIds = repository.findAllByOrderBySortName().stream() //
List<String> sortedIds = repository.findAllByOrderBySortName().stream() //
.map(it -> it.id).collect(Collectors.toList());
assertThat(sortedIds).containsExactly("5", "4", "3", "2", "1");
}
@Test // DATAES-937
public void shouldReturnEmptyListOnFindByIdWithEmptyInputList() {
Iterable<Product> products = repository.findAllById(new ArrayList<>());
assertThat(products).isEmpty();
}
@Test // DATAES-937
public void shouldReturnEmptyListOnDerivedMethodWithEmptyInputList() {
Iterable<Product> products = repository.findAllByNameIn(new ArrayList<>());
assertThat(products).isEmpty();
}
/**
* @author Mohsin Husen
* @author Artur Konczak
@@ -279,6 +296,8 @@ abstract class QueryKeywordsTests {
List<Product> findAllByOrderByText();
List<Product> findAllByOrderBySortName();
List<Product> findAllByNameIn(List<String> names);
}
}
@@ -23,6 +23,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.elasticsearch.ElasticsearchStatusException;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@@ -41,11 +42,11 @@ import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.annotation.Id;
@@ -69,7 +70,7 @@ import org.springframework.util.StringUtils;
/**
* @author Christoph Strobl
* @currentRead Fool's Fate - Robin Hobb
* @author Peter-Josef Meisch
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@@ -95,6 +96,11 @@ public class SimpleReactiveElasticsearchRepositoryTests {
TestUtils.deleteIndex(INDEX);
}
@After
public void after() {
TestUtils.deleteIndex(INDEX);
}
@Test // DATAES-519
public void saveShouldSaveSingleEntity() {
@@ -125,9 +131,11 @@ public class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete();
}
@Test // DATAES-519
public void findByIdShouldCompleteIfIndexDoesNotExist() {
repository.findById("id-two").as(StepVerifier::create).verifyComplete();
@Test // DATAES-519, DATAES-767
public void findByIdShouldErrorIfIndexDoesNotExist() {
repository.findById("id-two") //
.as(StepVerifier::create) //
.expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-519
@@ -169,9 +177,11 @@ public class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete();
}
@Test // DATAES-519
@Test // DATAES-519, DATAES-767
public void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() {
repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete();
repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create)
.expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-519
@@ -199,9 +209,10 @@ public class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete();
}
@Test // DATAES-519
@Test // DATAES-519, DATAE-767
public void countShouldReturnZeroWhenIndexDoesNotExist() {
repository.count().as(StepVerifier::create).expectNext(0L).verifyComplete();
repository.count().as(StepVerifier::create).expectNext(0L).expectError(ElasticsearchStatusException.class);
}
@Test // DATAES-519
@@ -287,9 +298,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
}
@Test // DATAES-519
public void deleteByIdShouldCompleteWhenIndexDoesNotExist() {
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
@Test // DATAES-519, DATAES-767
public void deleteByIdShouldErrorWhenIndexDoesNotExist() {
repository.deleteById("does-not-exist") //
.as(StepVerifier::create) //
.verifyError(ElasticsearchStatusException.class);
;
}
@Test // DATAES-519
@@ -1,3 +1,6 @@
#enabled scripts - this require groovy
#script.inline: true
#node.max_local_storage_nodes: 100
#node.max_local_storage_nodes: 100
cluster.routing.allocation.disk.watermark.low: 1gb
cluster.routing.allocation.disk.watermark.high: 1gb
cluster.routing.allocation.disk.watermark.flood_stage: 1gb
@@ -20,7 +20,7 @@
description=Adds "built in" analyzers to Elasticsearch.
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=analysis-common
@@ -35,7 +35,7 @@ classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=ingest-common
@@ -35,7 +35,7 @@ classname=org.elasticsearch.ingest.common.IngestCommonPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Lucene expressions integration for Elasticsearch
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=lang-expression
@@ -35,7 +35,7 @@ classname=org.elasticsearch.script.expression.ExpressionPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=An easy, safe and fast scripting language for Elasticsearch
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=lang-painless
@@ -35,7 +35,7 @@ classname=org.elasticsearch.painless.PainlessPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Adds advanced field mappers
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=mapper-extras
@@ -35,7 +35,7 @@ classname=org.elasticsearch.index.mapper.MapperExtrasPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=The Reindex module adds APIs to reindex from one index to another or update documents in place.
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=reindex
@@ -35,7 +35,7 @@ classname=org.elasticsearch.index.reindex.ReindexPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Module for URL repository
#
# 'version': plugin's version
version=6.8.4
version=6.8.13
#
# 'name': the plugin name
name=repository-url
@@ -35,7 +35,7 @@ classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=6.8.4
elasticsearch.version=6.8.13
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI