Compare commits

...

23 Commits
main ... 5.3.3

Author SHA1 Message Date
Jens Schauder
c931812c6a
Release version 5.3.3 (2024.0.3).
See #2939
2024-08-16 10:05:57 +02:00
Jens Schauder
c514e020b8
Prepare 5.3.3 (2024.0.3).
See #2939
2024-08-16 10:05:39 +02:00
Mark Paluch
31a4ad715f
Upgrade to Maven Wrapper 3.9.8.
See #2959
2024-08-08 10:23:16 +02:00
Mark Paluch
03efe1b910
Update CI properties.
See #2939
2024-08-08 10:19:20 +02:00
Peter-Josef Meisch
9d5d2efb40
Update versions.adoc 2024-08-07 18:41:12 +02:00
Eric Haag
b7266961d9
Migrate build to Spring Develocity Conventions extension.
* Migrate build to Spring Develocity Conventions extension.

* Adopt Develocity environment variables.

Closes #2944
2024-08-01 14:54:23 +02:00
Mark Paluch
d96cd02572
Bundle Javadoc with Antora documentation site.
Closes #2948.
2024-07-31 14:53:25 +02:00
Jens Schauder
ceb0225850
After release cleanups.
See #2932
2024-07-12 19:12:15 +02:00
Jens Schauder
5c59f73e00
Prepare next development iteration.
See #2932
2024-07-12 19:12:14 +02:00
Jens Schauder
44b1c9e848
Release version 5.3.2 (2024.0.2).
See #2932
2024-07-12 19:09:19 +02:00
Jens Schauder
1770f98a74
Prepare 5.3.2 (2024.0.2).
See #2932
2024-07-12 19:09:01 +02:00
Peter-Josef Meisch
bad0a80313
Enable use of search_after with field_collapse.
Original Pull Request #2937
Closes #2935

(cherry picked from commit dd156b9e29650f80c3aad91a6632734b7159b029)
2024-07-06 11:37:51 +02:00
Peter-Josef Meisch
92dd6e8599
Update migration-guide-5.2-5.3.adoc 2024-07-04 20:58:41 +02:00
Mark Paluch
c793be8ab4
Switch to Broadcom docker proxy.
Closes #2934
2024-06-20 11:21:08 +02:00
Mark Paluch
07ae79f9ce
After release cleanups.
See #2913
2024-06-14 10:48:00 +02:00
Mark Paluch
47c84b84af
Prepare next development iteration.
See #2913
2024-06-14 10:47:59 +02:00
Mark Paluch
5ba1e5dc77
Release version 5.3.1 (2024.0.1).
See #2913
2024-06-14 10:45:40 +02:00
Mark Paluch
5ddcd55942
Prepare 5.3.1 (2024.0.1).
See #2913
2024-06-14 10:45:24 +02:00
Peter-Josef Meisch
be4a77ad21
Update nav.adoc, add loink to migration guide 5.2 to 5.3 2024-05-27 19:39:26 +02:00
Peter-Josef Meisch
7fa3cb74a1
Upgrade to Elasticsearch 8.13.4.
Original Pull Request #2917
Closes #2916
2024-05-18 18:43:34 +00:00
Peter-Josef Meisch
ba9edf8ec8
Fix max dim value for dense vector.
Closes #2911

(cherry picked from commit e997b39f68bc0967c06c27a43e52b83afdb0b522)
2024-05-18 18:26:23 +02:00
Mark Paluch
e4a39ae285
After release cleanups.
See #2896
2024-05-17 12:03:29 +02:00
Mark Paluch
7392222793
Prepare next development iteration.
See #2896
2024-05-17 11:51:48 +02:00
28 changed files with 227 additions and 140 deletions

3
.gitignore vendored
View File

@ -30,7 +30,6 @@ target
build/ build/
node_modules node_modules
node node
package.json
package-lock.json package-lock.json
.mvn/.gradle-enterprise .mvn/.develocity

View File

@ -1,13 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<extensions> <extensions>
<extension> <extension>
<groupId>com.gradle</groupId> <groupId>io.spring.develocity.conventions</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId> <artifactId>develocity-conventions-maven-extension</artifactId>
<version>1.19.2</version> <version>0.0.19</version>
</extension>
<extension>
<groupId>com.gradle</groupId>
<artifactId>common-custom-user-data-maven-extension</artifactId>
<version>1.12.4</version>
</extension> </extension>
</extensions> </extensions>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<gradleEnterprise
xmlns="https://www.gradle.com/gradle-enterprise-maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.gradle.com/gradle-enterprise-maven https://www.gradle.com/schema/gradle-enterprise-maven.xsd">
<server>
<url>https://ge.spring.io</url>
</server>
<buildScan>
<backgroundBuildScanUpload>false</backgroundBuildScanUpload>
<captureGoalInputFiles>true</captureGoalInputFiles>
<publishIfAuthenticated>true</publishIfAuthenticated>
<obfuscation>
<ipAddresses>#{{'0.0.0.0'}}</ipAddresses>
</obfuscation>
</buildScan>
<buildCache>
<local>
<enabled>true</enabled>
</local>
<remote>
<server>
<credentials>
<username>${env.GRADLE_ENTERPRISE_CACHE_USERNAME}</username>
<password>${env.GRADLE_ENTERPRISE_CACHE_PASSWORD}</password>
</credentials>
</server>
<enabled>true</enabled>
<storeEnabled>#{env['GRADLE_ENTERPRISE_CACHE_USERNAME'] != null and env['GRADLE_ENTERPRISE_CACHE_PASSWORD'] != null}</storeEnabled>
</remote>
</buildCache>
</gradleEnterprise>

View File

@ -1,3 +1,3 @@
#Thu Dec 14 08:40:44 CET 2023 #Thu Aug 08 10:23:16 CEST 2024
wrapperUrl=https\://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar wrapperUrl=https\://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip

14
Jenkinsfile vendored
View File

@ -9,7 +9,7 @@ pipeline {
triggers { triggers {
pollSCM 'H/10 * * * *' pollSCM 'H/10 * * * *'
upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS) upstream(upstreamProjects: "spring-data-commons/3.3.x", threshold: hudson.model.Result.SUCCESS)
} }
options { options {
@ -33,12 +33,12 @@ pipeline {
environment { environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}") ARTIFACTORY = credentials("${p['artifactory.credentials']}")
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}") DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
} }
steps { steps {
script { script {
docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) { docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh" sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh"
sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh" sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
@ -46,6 +46,7 @@ pipeline {
} }
} }
} }
}
stage("Test other configurations") { stage("Test other configurations") {
when { when {
@ -63,11 +64,11 @@ pipeline {
options { timeout(time: 30, unit: 'MINUTES') } options { timeout(time: 30, unit: 'MINUTES') }
environment { environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}") ARTIFACTORY = credentials("${p['artifactory.credentials']}")
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}") DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
} }
steps { steps {
script { script {
docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) { docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) {
sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh" sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh"
sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh" sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
@ -77,6 +78,7 @@ pipeline {
} }
} }
} }
}
stage('Release to artifactory') { stage('Release to artifactory') {
when { when {
@ -92,16 +94,13 @@ pipeline {
options { timeout(time: 20, unit: 'MINUTES') } options { timeout(time: 20, unit: 'MINUTES') }
environment { environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}") ARTIFACTORY = credentials("${p['artifactory.credentials']}")
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}") DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
} }
steps { steps {
script { script {
docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) { docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
sh 'MAVEN_OPTS="-Duser.name=' + "${p['jenkins.user.name']}" + ' -Duser.home=/tmp/jenkins-home" ' + sh 'MAVEN_OPTS="-Duser.name=' + "${p['jenkins.user.name']}" + ' -Duser.home=/tmp/jenkins-home" ' +
"DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR} " +
"DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW} " +
"GRADLE_ENTERPRISE_ACCESS_KEY=${DEVELOCITY_ACCESS_KEY} " +
"./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch-non-root " + "./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch-non-root " +
"-Dartifactory.server=${p['artifactory.url']} " + "-Dartifactory.server=${p['artifactory.url']} " +
"-Dartifactory.username=${ARTIFACTORY_USR} " + "-Dartifactory.username=${ARTIFACTORY_USR} " +
@ -115,6 +114,7 @@ pipeline {
} }
} }
} }
}
post { post {
changed { changed {

View File

@ -2,12 +2,7 @@
set -euo pipefail set -euo pipefail
export DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR}
export DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW}
export JENKINS_USER=${JENKINS_USER_NAME} export JENKINS_USER=${JENKINS_USER_NAME}
# The environment variable to configure access key is still GRADLE_ENTERPRISE_ACCESS_KEY
export GRADLE_ENTERPRISE_ACCESS_KEY=${DEVELOCITY_ACCESS_KEY}
MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \ MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
./mvnw -s settings.xml clean -Dscan=false -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch ./mvnw -s settings.xml clean -Dscan=false -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch

View File

@ -1,10 +1,10 @@
# Java versions # Java versions
java.main.tag=17.0.9_9-jdk-focal java.main.tag=17.0.12_7-jdk-focal
java.next.tag=21.0.1_12-jdk-jammy java.next.tag=22.0.2_9-jdk-jammy
# Docker container images - standard # Docker container images - standard
docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag} docker.java.main.image=library/eclipse-temurin:${java.main.tag}
docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag} docker.java.next.image=library/eclipse-temurin:${java.next.tag}
# Supported versions of MongoDB # Supported versions of MongoDB
docker.mongodb.4.4.version=4.4.25 docker.mongodb.4.4.version=4.4.25
@ -14,6 +14,7 @@ docker.mongodb.7.0.version=7.0.2
# Supported versions of Redis # Supported versions of Redis
docker.redis.6.version=6.2.13 docker.redis.6.version=6.2.13
docker.redis.7.version=7.2.4
# Supported versions of Cassandra # Supported versions of Cassandra
docker.cassandra.3.version=3.11.16 docker.cassandra.3.version=3.11.16
@ -25,9 +26,10 @@ docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -
# Credentials # Credentials
docker.registry= docker.registry=
docker.credentials=hub.docker.com-springbuildmaster docker.credentials=hub.docker.com-springbuildmaster
docker.proxy.registry=https://docker-hub.usw1.packages.broadcom.com
docker.proxy.credentials=usw1_packages_broadcom_com-jenkins-token
artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c
artifactory.url=https://repo.spring.io artifactory.url=https://repo.spring.io
artifactory.repository.snapshot=libs-snapshot-local artifactory.repository.snapshot=libs-snapshot-local
develocity.cache.credentials=gradle_enterprise_cache_user
develocity.access-key=gradle_enterprise_secret_access_key develocity.access-key=gradle_enterprise_secret_access_key
jenkins.user.name=spring-builds+jenkins jenkins.user.name=spring-builds+jenkins

View File

@ -4,14 +4,8 @@ set -euo pipefail
mkdir -p /tmp/jenkins-home/.m2/spring-data-elasticsearch mkdir -p /tmp/jenkins-home/.m2/spring-data-elasticsearch
chown -R 1001:1001 . chown -R 1001:1001 .
export DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR}
export DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW}
export JENKINS_USER=${JENKINS_USER_NAME} export JENKINS_USER=${JENKINS_USER_NAME}
# The environment variable to configure access key is still GRADLE_ENTERPRISE_ACCESS_KEY
export GRADLE_ENTERPRISE_ACCESS_KEY=${DEVELOCITY_ACCESS_KEY}
MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \ MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
./mvnw -s settings.xml \ ./mvnw -s settings.xml \
-P${PROFILE} clean dependency:list verify -Dsort -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch -P${PROFILE} clean dependency:list verify -Dsort -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch

10
package.json Normal file
View File

@ -0,0 +1,10 @@
{
"dependencies": {
"antora": "3.2.0-alpha.6",
"@antora/atlas-extension": "1.0.0-alpha.2",
"@antora/collector-extension": "1.0.0-alpha.7",
"@asciidoctor/tabs": "1.0.0-beta.6",
"@springio/antora-extensions": "1.13.0",
"@springio/asciidoctor-extensions": "1.0.0-alpha.11"
}
}

10
pom.xml
View File

@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId> <artifactId>spring-data-elasticsearch</artifactId>
<version>5.3.0</version> <version>5.3.3</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>3.3.0</version> <version>3.3.3</version>
</parent> </parent>
<name>Spring Data Elasticsearch</name> <name>Spring Data Elasticsearch</name>
@ -18,10 +18,10 @@
<url>https://github.com/spring-projects/spring-data-elasticsearch</url> <url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties> <properties>
<springdata.commons>3.3.0</springdata.commons> <springdata.commons>3.3.3</springdata.commons>
<!-- version of the ElasticsearchClient --> <!-- version of the ElasticsearchClient -->
<elasticsearch-java>8.13.2</elasticsearch-java> <elasticsearch-java>8.13.4</elasticsearch-java>
<blockhound-junit>1.0.8.RELEASE</blockhound-junit> <blockhound-junit>1.0.8.RELEASE</blockhound-junit>
<hoverfly>0.14.4</hoverfly> <hoverfly>0.14.4</hoverfly>
@ -479,7 +479,7 @@
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>io.spring.maven.antora</groupId> <groupId>org.antora</groupId>
<artifactId>antora-maven-plugin</artifactId> <artifactId>antora-maven-plugin</artifactId>
</plugin> </plugin>
</plugins> </plugins>

View File

@ -3,8 +3,7 @@
# The purpose of this Antora playbook is to build the docs in the current branch. # The purpose of this Antora playbook is to build the docs in the current branch.
antora: antora:
extensions: extensions:
- '@antora/collector-extension' - require: '@springio/antora-extensions'
- require: '@springio/antora-extensions/root-component-extension'
root_component_name: 'data-elasticsearch' root_component_name: 'data-elasticsearch'
site: site:
title: Spring Data Elasticsearch title: Spring Data Elasticsearch
@ -22,13 +21,12 @@ content:
start_path: src/main/antora start_path: src/main/antora
asciidoc: asciidoc:
attributes: attributes:
page-pagination: ''
hide-uri-scheme: '@' hide-uri-scheme: '@'
tabs-sync-option: '@' tabs-sync-option: '@'
chomp: 'all'
extensions: extensions:
- '@asciidoctor/tabs' - '@asciidoctor/tabs'
- '@springio/asciidoctor-extensions' - '@springio/asciidoctor-extensions'
- '@springio/asciidoctor-extensions/javadoc-extension'
sourcemap: true sourcemap: true
urls: urls:
latest_version_segment: '' latest_version_segment: ''
@ -38,5 +36,5 @@ runtime:
format: pretty format: pretty
ui: ui:
bundle: bundle:
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
snapshot: true snapshot: true

View File

@ -10,3 +10,8 @@ ext:
local: true local: true
scan: scan:
dir: target/classes/ dir: target/classes/
- run:
command: ./mvnw package -Pdistribute
local: true
scan:
dir: target/antora

View File

@ -9,7 +9,7 @@
*** xref:migration-guides/migration-guide-4.4-5.0.adoc[] *** xref:migration-guides/migration-guide-4.4-5.0.adoc[]
*** xref:migration-guides/migration-guide-5.0-5.1.adoc[] *** xref:migration-guides/migration-guide-5.0-5.1.adoc[]
*** xref:migration-guides/migration-guide-5.1-5.2.adoc[] *** xref:migration-guides/migration-guide-5.1-5.2.adoc[]
*** xref:migration-guides/migration-guide-5.2-5.3.adoc[]
* xref:elasticsearch.adoc[] * xref:elasticsearch.adoc[]
** xref:elasticsearch/clients.adoc[] ** xref:elasticsearch/clients.adoc[]
@ -39,4 +39,5 @@
** xref:repositories/query-keywords-reference.adoc[] ** xref:repositories/query-keywords-reference.adoc[]
** xref:repositories/query-return-types-reference.adoc[] ** xref:repositories/query-return-types-reference.adoc[]
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki] * xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank]
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki,role=link-external,window=_blank]

View File

@ -31,7 +31,7 @@ public class MyClientConfig extends ElasticsearchConfiguration {
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration] <.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
==== ====
The `ElasticsearchConfiguration` class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods. The javadoc:org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration[]] class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
The following beans can then be injected in other Spring components: The following beans can then be injected in other Spring components:
@ -52,13 +52,13 @@ RestClient restClient; <.>
JsonpMapper jsonpMapper; <.> JsonpMapper jsonpMapper; <.>
---- ----
<.> an implementation of `ElasticsearchOperations` <.> an implementation of javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[]
<.> the `co.elastic.clients.elasticsearch.ElasticsearchClient` that is used. <.> the `co.elastic.clients.elasticsearch.ElasticsearchClient` that is used.
<.> the low level `RestClient` from the Elasticsearch libraries <.> the low level `RestClient` from the Elasticsearch libraries
<.> the `JsonpMapper` user by the Elasticsearch `Transport` <.> the `JsonpMapper` user by the Elasticsearch `Transport`
==== ====
Basically one should just use the `ElasticsearchOperations` to interact with the Elasticsearch cluster. Basically one should just use the javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[] to interact with the Elasticsearch cluster.
When using repositories, this instance is used under the hood as well. When using repositories, this instance is used under the hood as well.
[[elasticsearch.clients.reactiverestclient]] [[elasticsearch.clients.reactiverestclient]]
@ -86,7 +86,7 @@ public class MyClientConfig extends ReactiveElasticsearchConfiguration {
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration] <.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
==== ====
The `ReactiveElasticsearchConfiguration` class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods. The javadoc:org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchConfiguration[] class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
The following beans can then be injected in other Spring components: The following beans can then be injected in other Spring components:
@ -108,20 +108,20 @@ JsonpMapper jsonpMapper; <.>
the following can be injected: the following can be injected:
<.> an implementation of `ReactiveElasticsearchOperations` <.> an implementation of javadoc:org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations[]
<.> the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient` that is used. <.> the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient` that is used.
This is a reactive implementation based on the Elasticsearch client implementation. This is a reactive implementation based on the Elasticsearch client implementation.
<.> the low level `RestClient` from the Elasticsearch libraries <.> the low level `RestClient` from the Elasticsearch libraries
<.> the `JsonpMapper` user by the Elasticsearch `Transport` <.> the `JsonpMapper` user by the Elasticsearch `Transport`
==== ====
Basically one should just use the `ReactiveElasticsearchOperations` to interact with the Elasticsearch cluster. Basically one should just use the javadoc:org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations[] to interact with the Elasticsearch cluster.
When using repositories, this instance is used under the hood as well. When using repositories, this instance is used under the hood as well.
[[elasticsearch.clients.configuration]] [[elasticsearch.clients.configuration]]
== Client Configuration == Client Configuration
Client behaviour can be changed via the `ClientConfiguration` that allows to set options for SSL, connect and socket timeouts, headers and other parameters. Client behaviour can be changed via the javadoc:org.springframework.data.elasticsearch.client.ClientConfiguration[] that allows to set options for SSL, connect and socket timeouts, headers and other parameters.
.Client Configuration .Client Configuration
==== ====
@ -178,7 +178,7 @@ If this is used in the reactive setup, the supplier function *must not* block!
[[elasticsearch.clients.configuration.callbacks]] [[elasticsearch.clients.configuration.callbacks]]
=== Client configuration callbacks === Client configuration callbacks
The `ClientConfiguration` class offers the most common parameters to configure the client. The javadoc:org.springframework.data.elasticsearch.client.ClientConfiguration[] class offers the most common parameters to configure the client.
In the case this is not enough, the user can add callback functions by using the `withClientConfigurer(ClientConfigurationCallback<?>)` method. In the case this is not enough, the user can add callback functions by using the `withClientConfigurer(ClientConfigurationCallback<?>)` method.
The following callbacks are provided: The following callbacks are provided:

View File

@ -1,6 +1,11 @@
[[new-features]] [[new-features]]
= What's new = What's new
[[new-features.5-3-1]]
== New in Spring Data Elasticsearch 5.3.1
* Upgrade to Elasticsearch 8.13.4.
[[new-features.5-3-0]] [[new-features.5-3-0]]
== New in Spring Data Elasticsearch 5.3 == New in Spring Data Elasticsearch 5.3

View File

@ -3,10 +3,10 @@
Spring Data Elasticsearch uses several interfaces to define the operations that can be called against an Elasticsearch index (for a description of the reactive interfaces see xref:elasticsearch/reactive-template.adoc[]). Spring Data Elasticsearch uses several interfaces to define the operations that can be called against an Elasticsearch index (for a description of the reactive interfaces see xref:elasticsearch/reactive-template.adoc[]).
* `IndexOperations` defines actions on index level like creating or deleting an index. * javadoc:org.springframework.data.elasticsearch.core.IndexOperations[] defines actions on index level like creating or deleting an index.
* `DocumentOperations` defines actions to store, update and retrieve entities based on their id. * javadoc:org.springframework.data.elasticsearch.core.DocumentOperations[] defines actions to store, update and retrieve entities based on their id.
* `SearchOperations` define the actions to search for multiple entities using queries * javadoc:org.springframework.data.elasticsearch.core.SearchOperations[] define the actions to search for multiple entities using queries
* `ElasticsearchOperations` combines the `DocumentOperations` and `SearchOperations` interfaces. * javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[] combines the `DocumentOperations` and `SearchOperations` interfaces.
These interfaces correspond to the structuring of the https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html[Elasticsearch API]. These interfaces correspond to the structuring of the https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html[Elasticsearch API].

View File

@ -6,7 +6,7 @@ The following table shows the Elasticsearch and Spring versions that are used by
[cols="^,^,^,^",options="header"] [cols="^,^,^,^",options="header"]
|=== |===
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework | Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
| 2024.0 (?) | 5.3.x | 8.13.2 | ? | 2024.0 | 5.3.3 | 8.13.4 | 6.1.x
| 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x | 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x
| 2023.0 (Ullmann) | 5.1.x | 8.7.1 | 6.0.x | 2023.0 (Ullmann) | 5.1.x | 8.7.1 | 6.0.x
| 2022.0 (Turing) | 5.0.xfootnote:oom[Out of maintenance] | 8.5.3 | 6.0.x | 2022.0 (Turing) | 5.0.xfootnote:oom[Out of maintenance] | 8.5.3 | 6.0.x

View File

@ -5,7 +5,10 @@ This section describes breaking changes from version 5.2.x to 5.3.x and how remo
[[elasticsearch-migration-guide-5.2-5.3.breaking-changes]] [[elasticsearch-migration-guide-5.2-5.3.breaking-changes]]
== Breaking Changes == Breaking Changes
During the parameter replacement in `@Query` annotated repository methods previous versions wrote the String _"null"_ into the query that was sent to Elasticsearch
when the actual parameter value was `null`. As Elasticsearch does not store `null` values, this behaviour could lead to problems, for example whent the fields to be
searched contains the string `"null"`. In Version 5.3 a `null` value in a parameter will cause a `ConversionException` to be thrown. If you are using `"null"` as the
`null_value` defined in a field mapping, then pass that string into the query instead of a Java `null`.
[[elasticsearch-migration-guide-5.2-5.3.deprecations]] [[elasticsearch-migration-guide-5.2-5.3.deprecations]]
== Deprecations == Deprecations

View File

@ -16,6 +16,7 @@
package org.springframework.data.elasticsearch.client.elc; package org.springframework.data.elasticsearch.client.elc;
import co.elastic.clients.elasticsearch._types.KnnQuery; import co.elastic.clients.elasticsearch._types.KnnQuery;
import co.elastic.clients.elasticsearch._types.KnnSearch;
import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.SortOptions;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation; import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch._types.query_dsl.Query;
@ -54,6 +55,7 @@ public class NativeQuery extends BaseQuery {
private Map<String, JsonData> searchExtensions = Collections.emptyMap(); private Map<String, JsonData> searchExtensions = Collections.emptyMap();
@Nullable private KnnQuery knnQuery; @Nullable private KnnQuery knnQuery;
@Nullable private List<KnnSearch> knnSearches = Collections.emptyList();
public NativeQuery(NativeQueryBuilder builder) { public NativeQuery(NativeQueryBuilder builder) {
super(builder); super(builder);
@ -71,6 +73,7 @@ public class NativeQuery extends BaseQuery {
} }
this.springDataQuery = builder.getSpringDataQuery(); this.springDataQuery = builder.getSpringDataQuery();
this.knnQuery = builder.getKnnQuery(); this.knnQuery = builder.getKnnQuery();
this.knnSearches = builder.getKnnSearches();
} }
public NativeQuery(@Nullable Query query) { public NativeQuery(@Nullable Query query) {
@ -129,6 +132,14 @@ public class NativeQuery extends BaseQuery {
return knnQuery; return knnQuery;
} }
/**
* @since 5.3.1
*/
@Nullable
public List<KnnSearch> getKnnSearches() {
return knnSearches;
}
@Nullable @Nullable
public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() { public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() {
return springDataQuery; return springDataQuery;

View File

@ -16,6 +16,7 @@
package org.springframework.data.elasticsearch.client.elc; package org.springframework.data.elasticsearch.client.elc;
import co.elastic.clients.elasticsearch._types.KnnQuery; import co.elastic.clients.elasticsearch._types.KnnQuery;
import co.elastic.clients.elasticsearch._types.KnnSearch;
import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.SortOptions;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation; import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch._types.query_dsl.Query;
@ -26,6 +27,7 @@ import co.elastic.clients.util.ObjectBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -52,6 +54,7 @@ public class NativeQueryBuilder extends BaseQueryBuilder<NativeQuery, NativeQuer
@Nullable private org.springframework.data.elasticsearch.core.query.Query springDataQuery; @Nullable private org.springframework.data.elasticsearch.core.query.Query springDataQuery;
@Nullable private KnnQuery knnQuery; @Nullable private KnnQuery knnQuery;
@Nullable private List<KnnSearch> knnSearches = Collections.emptyList();
public NativeQueryBuilder() {} public NativeQueryBuilder() {}
@ -92,6 +95,14 @@ public class NativeQueryBuilder extends BaseQueryBuilder<NativeQuery, NativeQuer
return knnQuery; return knnQuery;
} }
/**
* @since 5.3.1
*/
@Nullable
public List<KnnSearch> getKnnSearches() {
return knnSearches;
}
@Nullable @Nullable
public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() { public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() {
return springDataQuery; return springDataQuery;

View File

@ -395,7 +395,28 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
Function<PitSearchAfter, Publisher<? extends ResponseBody<EntityAsMap>>> resourceClosure = psa -> { Function<PitSearchAfter, Publisher<? extends ResponseBody<EntityAsMap>>> resourceClosure = psa -> {
baseQuery.setPointInTime(new Query.PointInTime(psa.getPit(), pitKeepAlive)); baseQuery.setPointInTime(new Query.PointInTime(psa.getPit(), pitKeepAlive));
// only add _shard_doc if there is not a field_collapse and a sort with the same name
boolean addShardDoc = true;
if (query instanceof NativeQuery nativeQuery && nativeQuery.getFieldCollapse() != null) {
var field = nativeQuery.getFieldCollapse().field();
if (nativeQuery.getSortOptions().stream()
.anyMatch(sortOptions -> sortOptions.isField() && sortOptions.field().field().equals(field))) {
addShardDoc = false;
}
if (query.getSort() != null
&& query.getSort().stream().anyMatch(order -> order.getProperty().equals(field))) {
addShardDoc = false;
}
}
if (addShardDoc) {
baseQuery.addSort(Sort.by("_shard_doc")); baseQuery.addSort(Sort.by("_shard_doc"));
}
SearchRequest firstSearchRequest = requestConverter.searchRequest(baseQuery, routingResolver.getRouting(), SearchRequest firstSearchRequest = requestConverter.searchRequest(baseQuery, routingResolver.getRouting(),
clazz, index, false, true); clazz, index, false, true);

View File

@ -1477,8 +1477,8 @@ class RequestConverter extends AbstractQueryProcessor {
if (query instanceof NativeQuery nativeQuery) { if (query instanceof NativeQuery nativeQuery) {
prepareNativeSearch(nativeQuery, builder); prepareNativeSearch(nativeQuery, builder);
} }
// query.getSort() must be checked after prepareNativeSearch as this already might hav a sort set that must have // query.getSort() must be checked after prepareNativeSearch as this already might have a sort set
// higher priority // that must have higher priority
if (query.getSort() != null) { if (query.getSort() != null) {
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity); List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
@ -1500,7 +1500,15 @@ class RequestConverter extends AbstractQueryProcessor {
} }
if (!isEmpty(query.getSearchAfter())) { if (!isEmpty(query.getSearchAfter())) {
builder.searchAfter(query.getSearchAfter().stream().map(TypeUtils::toFieldValue).toList()); var fieldValues = query.getSearchAfter().stream().map(TypeUtils::toFieldValue).toList();
// when there is a field collapse on a native query, and we have a search_after, then the search_after
// must only have one entry
if (query instanceof NativeQuery nativeQuery && nativeQuery.getFieldCollapse() != null) {
builder.searchAfter(fieldValues.get(0));
} else {
builder.searchAfter(fieldValues);
}
} }
query.getRescorerQueries().forEach(rescorerQuery -> builder.rescore(getRescore(rescorerQuery))); query.getRescorerQueries().forEach(rescorerQuery -> builder.rescore(getRescore(rescorerQuery)));
@ -1719,7 +1727,18 @@ class RequestConverter extends AbstractQueryProcessor {
; ;
if (query.getKnnQuery() != null) { if (query.getKnnQuery() != null) {
builder.knn(query.getKnnQuery()); var kq = query.getKnnQuery();
builder.knn(ksb -> ksb
.field(kq.field())
.queryVector(kq.queryVector())
.numCandidates(kq.numCandidates())
.filter(kq.filter())
.similarity(kq.similarity()));
}
if (!isEmpty(query.getKnnSearches())) {
builder.knn(query.getKnnSearches());
} }
if (!isEmpty(query.getAggregations())) { if (!isEmpty(query.getAggregations())) {
@ -1740,7 +1759,18 @@ class RequestConverter extends AbstractQueryProcessor {
.sort(query.getSortOptions()); .sort(query.getSortOptions());
if (query.getKnnQuery() != null) { if (query.getKnnQuery() != null) {
builder.knn(query.getKnnQuery()); var kq = query.getKnnQuery();
builder.knn(ksb -> ksb
.field(kq.field())
.queryVector(kq.queryVector())
.numCandidates(kq.numCandidates())
.filter(kq.filter())
.similarity(kq.similarity()));
}
if (!isEmpty(query.getKnnSearches())) {
builder.knn(query.getKnnSearches());
} }
if (!isEmpty(query.getAggregations())) { if (!isEmpty(query.getAggregations())) {

View File

@ -171,8 +171,8 @@ public final class MappingParameters {
positiveScoreImpact = field.positiveScoreImpact(); positiveScoreImpact = field.positiveScoreImpact();
dims = field.dims(); dims = field.dims();
if (type == FieldType.Dense_Vector) { if (type == FieldType.Dense_Vector) {
Assert.isTrue(dims >= 1 && dims <= 2048, Assert.isTrue(dims >= 1 && dims <= 4096,
"Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 2048."); "Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 4096.");
} }
Assert.isTrue(field.enabled() || type == FieldType.Object, "enabled false is only allowed for field type object"); Assert.isTrue(field.enabled() || type == FieldType.Object, "enabled false is only allowed for field type object");
enabled = field.enabled(); enabled = field.enabled();
@ -214,8 +214,8 @@ public final class MappingParameters {
positiveScoreImpact = field.positiveScoreImpact(); positiveScoreImpact = field.positiveScoreImpact();
dims = field.dims(); dims = field.dims();
if (type == FieldType.Dense_Vector) { if (type == FieldType.Dense_Vector) {
Assert.isTrue(dims >= 1 && dims <= 2048, Assert.isTrue(dims >= 1 && dims <= 4096,
"Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 2048."); "Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 4096.");
} }
enabled = true; enabled = true;
eagerGlobalOrdinals = field.eagerGlobalOrdinals(); eagerGlobalOrdinals = field.eagerGlobalOrdinals();

View File

@ -1,4 +1,4 @@
Spring Data Elasticsearch 5.3 GA (2024.0.0) Spring Data Elasticsearch 5.3.3 (2024.0.3)
Copyright (c) [2013-2022] Pivotal Software, Inc. Copyright (c) [2013-2022] 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").
@ -22,3 +22,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file.

View File

@ -70,8 +70,8 @@ public class MappingParametersTest extends MappingContextBaseTests {
} }
@Test // #1700 @Test // #1700
@DisplayName("should not allow dims length greater than 2048 for dense_vector type") @DisplayName("should not allow dims length greater than 4096 for dense_vector type")
void shouldNotAllowDimsLengthGreaterThan2048ForDenseVectorType() { void shouldNotAllowDimsLengthGreaterThan4096ForDenseVectorType() {
ElasticsearchPersistentEntity<?> failEntity = elasticsearchConverter.get().getMappingContext() ElasticsearchPersistentEntity<?> failEntity = elasticsearchConverter.get().getMappingContext()
.getRequiredPersistentEntity(DenseVectorInvalidDimsClass.class); .getRequiredPersistentEntity(DenseVectorInvalidDimsClass.class);
Annotation annotation = failEntity.getRequiredPersistentProperty("dense_vector").findAnnotation(Field.class); Annotation annotation = failEntity.getRequiredPersistentProperty("dense_vector").findAnnotation(Field.class);
@ -90,21 +90,28 @@ public class MappingParametersTest extends MappingContextBaseTests {
} }
static class AnnotatedClass { static class AnnotatedClass {
@Nullable @Field private String field; @Nullable
@Nullable @MultiField(mainField = @Field, @Field private String field;
@Nullable
@MultiField(mainField = @Field,
otherFields = { @InnerField(suffix = "test", type = FieldType.Text) }) private String mainField; otherFields = { @InnerField(suffix = "test", type = FieldType.Text) }) private String mainField;
@Nullable @Field(type = FieldType.Text, docValues = false) private String docValuesText; @Nullable
@Nullable @Field(type = FieldType.Nested, docValues = false) private String docValuesNested; @Field(type = FieldType.Text, docValues = false) private String docValuesText;
@Nullable @Field(type = Object, enabled = true) private String enabledObject; @Nullable
@Nullable @Field(type = Object, enabled = false) private String disabledObject; @Field(type = FieldType.Nested, docValues = false) private String docValuesNested;
@Nullable
@Field(type = Object, enabled = true) private String enabledObject;
@Nullable
@Field(type = Object, enabled = false) private String disabledObject;
} }
static class InvalidEnabledFieldClass { static class InvalidEnabledFieldClass {
@Nullable @Field(type = FieldType.Text, enabled = false) private String disabledObject; @Nullable
@Field(type = FieldType.Text, enabled = false) private String disabledObject;
} }
static class DenseVectorInvalidDimsClass { static class DenseVectorInvalidDimsClass {
@Field(type = Dense_Vector, dims = 2049) private float[] dense_vector; @Field(type = Dense_Vector, dims = 4097) private float[] dense_vector;
} }
static class DenseVectorMissingDimsClass { static class DenseVectorMissingDimsClass {

View File

@ -132,7 +132,7 @@ public class ClusterConnection implements ExtensionContext.Store.CloseableResour
DockerImageName dockerImageName = getDockerImageName(testcontainersProperties); DockerImageName dockerImageName = getDockerImageName(testcontainersProperties);
ElasticsearchContainer elasticsearchContainer = new SpringDataElasticsearchContainer(dockerImageName) ElasticsearchContainer elasticsearchContainer = new SpringDataElasticsearchContainer(dockerImageName)
.withEnv(testcontainersProperties).withStartupTimeout(Duration.ofMinutes(2)); .withEnv(testcontainersProperties).withStartupTimeout(Duration.ofMinutes(2)).withReuse(true);
elasticsearchContainer.start(); elasticsearchContainer.start();
return ClusterConnectionInfo.builder() // return ClusterConnectionInfo.builder() //
@ -192,16 +192,7 @@ public class ClusterConnection implements ExtensionContext.Store.CloseableResour
@Override @Override
public void close() { public void close() {
if (clusterConnectionInfo != null && clusterConnectionInfo.getElasticsearchContainer() != null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Stopping container");
}
clusterConnectionInfo.getElasticsearchContainer().stop();
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("closed");
}
} }
private static class SpringDataElasticsearchContainer extends ElasticsearchContainer { private static class SpringDataElasticsearchContainer extends ElasticsearchContainer {

View File

@ -15,14 +15,22 @@
*/ */
package org.springframework.data.elasticsearch.repository.support; package org.springframework.data.elasticsearch.repository.support;
import co.elastic.clients.elasticsearch.core.search.FieldCollapse;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.Queries;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.repositories.custommethod.QueryParameter; import org.springframework.data.elasticsearch.repositories.custommethod.QueryParameter;
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
import org.springframework.data.elasticsearch.utils.IndexNameProvider; import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import reactor.test.StepVerifier;
/** /**
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
@ -51,4 +59,33 @@ public class SimpleReactiveElasticsearchRepositoryELCIntegrationTests
} }
} }
/**
* search_after is used by the reactive search operation, it normally always adds _shard_doc as a tiebreaker sort
* parameter. This must not be done when a collapse field is used as sort field, as in that case the collapse field
* must be the only sort field.
*/
@Test // #2935
@DisplayName("should use collapse_field for search_after in pit search")
void shouldUseCollapseFieldForSearchAfterI() {
var entity = new SampleEntity();
entity.setId("42");
entity.setMessage("m");
entity.setKeyword("kw");
repository.save(entity).block();
var query = NativeQuery.builder()
.withQuery(Queries.matchAllQueryAsQuery())
.withPageable(Pageable.unpaged())
.withFieldCollapse(FieldCollapse.of(fcb -> fcb
.field("keyword")))
.withSort(Sort.by("keyword"))
.build();
operations.search(query, SampleEntity.class)
.as(StepVerifier::create)
.expectNextCount(1)
.verifyComplete();
}
} }

View File

@ -15,7 +15,7 @@
# #
# #
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
sde.testcontainers.image-version=8.13.2 sde.testcontainers.image-version=8.13.4
# #
# #
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13 # needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13