diff --git a/.gitignore b/.gitignore
index ea0475e148..449f58ea44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,7 +30,7 @@ target
build/
node_modules
node
-package.json
package-lock.json
-.mvn/.gradle-enterprise
+.mvn/.develocity
+/src/test/resources/testcontainers-local.properties
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
index ebd7610255..e0857eaa25 100644
--- a/.mvn/extensions.xml
+++ b/.mvn/extensions.xml
@@ -1,13 +1,8 @@
- com.gradle
- gradle-enterprise-maven-extension
- 1.19.2
-
-
- com.gradle
- common-custom-user-data-maven-extension
- 1.12.4
+ io.spring.develocity.conventions
+ develocity-conventions-maven-extension
+ 0.0.22
diff --git a/.mvn/gradle-enterprise.xml b/.mvn/gradle-enterprise.xml
deleted file mode 100644
index f88a885d06..0000000000
--- a/.mvn/gradle-enterprise.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- https://ge.spring.io
-
-
- false
- true
- true
-
- #{{'0.0.0.0'}}
-
-
-
-
- true
-
-
-
-
- ${env.GRADLE_ENTERPRISE_CACHE_USERNAME}
- ${env.GRADLE_ENTERPRISE_CACHE_PASSWORD}
-
-
- true
- #{env['GRADLE_ENTERPRISE_CACHE_USERNAME'] != null and env['GRADLE_ENTERPRISE_CACHE_PASSWORD'] != null}
-
-
-
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 0000000000..e27f6e8f5e
--- /dev/null
+++ b/.mvn/jvm.config
@@ -0,0 +1,14 @@
+--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+--add-opens=java.base/java.util=ALL-UNNAMED
+--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
+--add-opens=java.base/java.text=ALL-UNNAMED
+--add-opens=java.desktop/java.awt.font=ALL-UNNAMED
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index e6686c6c0c..e075a74d86 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,3 +1,3 @@
-#Thu Dec 14 08:40:44 CET 2023
+#Thu Nov 07 09:47:28 CET 2024
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.9/apache-maven-3.9.9-bin.zip
diff --git a/Jenkinsfile b/Jenkinsfile
index ade2e5a109..1d2500ed1e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -33,15 +33,16 @@ pipeline {
environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
- DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
}
steps {
script {
- 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 "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
+ docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
+ 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 "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
+ }
}
}
}
@@ -63,14 +64,15 @@ pipeline {
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
- DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
}
steps {
script {
- 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 "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
+ docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
+ 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 "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
+ }
}
}
}
@@ -92,24 +94,24 @@ pipeline {
options { timeout(time: 20, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
- DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
}
steps {
script {
- 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" ' +
- "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 " +
- "-Dartifactory.server=${p['artifactory.url']} " +
- "-Dartifactory.username=${ARTIFACTORY_USR} " +
- "-Dartifactory.password=${ARTIFACTORY_PSW} " +
- "-Dartifactory.staging-repository=${p['artifactory.repository.snapshot']} " +
- "-Dartifactory.build-name=spring-data-elasticsearch " +
- "-Dartifactory.build-number=spring-data-elasticsearch-${BRANCH_NAME}-build-${BUILD_NUMBER} " +
- "-Dmaven.test.skip=true clean deploy -U -B"
+ docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
+ docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
+ sh 'MAVEN_OPTS="-Duser.name=' + "${p['jenkins.user.name']}" + ' -Duser.home=/tmp/jenkins-home" ' +
+ "./mvnw -s settings.xml -Pci,artifactory " +
+ "-Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root " +
+ "-Dartifactory.server=${p['artifactory.url']} " +
+ "-Dartifactory.username=${ARTIFACTORY_USR} " +
+ "-Dartifactory.password=${ARTIFACTORY_PSW} " +
+ "-Dartifactory.staging-repository=${p['artifactory.repository.snapshot']} " +
+ "-Dartifactory.build-name=spring-data-elasticsearch " +
+ "-Dartifactory.build-number=spring-data-elasticsearch-${BRANCH_NAME}-build-${BUILD_NUMBER} " +
+ "-Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch " +
+ "-Dmaven.test.skip=true clean deploy -U -B"
+ }
}
}
}
diff --git a/README.adoc b/README.adoc
index 72860e181b..0242089d82 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,5 +1,3 @@
-image:https://spring.io/badges/spring-data-elasticsearch/ga.svg[Spring Data Elasticsearch,link=https://projects.spring.io/spring-data-elasticsearch#quick-start] image:https://spring.io/badges/spring-data-elasticsearch/snapshot.svg[Spring Data Elasticsearch,link=https://projects.spring.io/spring-data-elasticsearch#quick-start]
-
= Spring Data for Elasticsearch image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2Fmain&subject=Build[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] https://gitter.im/spring-projects/spring-data[image:https://badges.gitter.im/spring-projects/spring-data.svg[Gitter]] image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Develocity", link="https://ge.spring.io/scans?search.rootProjectNames=Spring%20Data%20Elasticsearch"]
The primary goal of the https://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
@@ -64,7 +62,7 @@ public class MyService {
=== Using the RestClient
-Please check the [official documentation](https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration).
+Please check the https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration[official documentation].
=== Maven configuration
@@ -126,8 +124,7 @@ We’d love to help!
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/[reference documentation], and https://docs.spring.io/spring-data/elasticsearch/docs/current/api/[Javadocs].
* Learn the Spring basics – Spring Data builds on Spring Framework, check the https://spring.io[spring.io] web-site for a wealth of reference documentation.
If you are just starting out with Spring, try one of the https://spring.io/guides[guides].
-* Ask a question - we monitor https://stackoverflow.com[stackoverflow.com] for questions tagged with https://stackoverflow.com/tags/spring-data[`spring-data-elasticsearch`].
-You can also chat with the community on https://gitter.im/spring-projects/spring-data[Gitter].
+* Ask a question or chat with the community on https://app.gitter.im/#/room/#spring-projects_spring-data:gitter.im[Gitter].
* Report bugs with Spring Data for Elasticsearch at https://github.com/spring-projects/spring-data-elasticsearch/issues[https://github.com/spring-projects/spring-data-elasticsearch/issues].
== Reporting Issues
@@ -171,7 +168,7 @@ Building the documentation builds also the project without running tests.
$ ./mvnw clean install -Pantora
----
-The generated documentation is available from `target/antora/site/index.html`.
+The generated documentation is available from `target/site/index.html`.
== Examples
diff --git a/ci/clean.sh b/ci/clean.sh
index 34ba4ffcc1..ca174330ee 100755
--- a/ci/clean.sh
+++ b/ci/clean.sh
@@ -2,12 +2,7 @@
set -euo pipefail
-export DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR}
-export DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW}
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" \
- ./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 -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
diff --git a/ci/pipeline.properties b/ci/pipeline.properties
index 60057f2659..cde4a8e881 100644
--- a/ci/pipeline.properties
+++ b/ci/pipeline.properties
@@ -1,22 +1,19 @@
# Java versions
-java.main.tag=17.0.9_9-jdk-focal
-java.next.tag=21.0.1_12-jdk-jammy
+java.main.tag=24.0.1_9-jdk-noble
+java.next.tag=24.0.1_9-jdk-noble
# Docker container images - standard
-docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/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.main.image=library/eclipse-temurin:${java.main.tag}
+docker.java.next.image=library/eclipse-temurin:${java.next.tag}
# Supported versions of MongoDB
-docker.mongodb.4.4.version=4.4.25
-docker.mongodb.5.0.version=5.0.21
-docker.mongodb.6.0.version=6.0.10
-docker.mongodb.7.0.version=7.0.2
+docker.mongodb.6.0.version=6.0.23
+docker.mongodb.7.0.version=7.0.20
+docker.mongodb.8.0.version=8.0.9
# Supported versions of Redis
docker.redis.6.version=6.2.13
-
-# Supported versions of Cassandra
-docker.cassandra.3.version=3.11.16
+docker.redis.7.version=7.2.4
# Docker environment settings
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
@@ -25,9 +22,10 @@ docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -
# Credentials
docker.registry=
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.url=https://repo.spring.io
artifactory.repository.snapshot=libs-snapshot-local
-develocity.cache.credentials=gradle_enterprise_cache_user
develocity.access-key=gradle_enterprise_secret_access_key
jenkins.user.name=spring-builds+jenkins
diff --git a/ci/verify.sh b/ci/verify.sh
index 98b9c79cc6..46afc80280 100755
--- a/ci/verify.sh
+++ b/ci/verify.sh
@@ -3,15 +3,8 @@
set -euo pipefail
mkdir -p /tmp/jenkins-home/.m2/spring-data-elasticsearch
-chown -R 1001:1001 .
-
-export DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR}
-export DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW}
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" \
./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 -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
diff --git a/package.json b/package.json
new file mode 100644
index 0000000000..4689506b3f
--- /dev/null
+++ b/package.json
@@ -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"
+ }
+}
diff --git a/pom.xml b/pom.xml
index 1e35a6d69f..4396ce5a62 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,12 +5,12 @@
org.springframework.dataspring-data-elasticsearch
- 5.3.0-SNAPSHOT
+ 6.0.0-SNAPSHOTorg.springframework.data.buildspring-data-parent
- 3.3.0-SNAPSHOT
+ 4.0.0-SNAPSHOTSpring Data Elasticsearch
@@ -18,17 +18,16 @@
https://github.com/spring-projects/spring-data-elasticsearch
- 3.3.0-SNAPSHOT
+ 4.0.0-SNAPSHOT
- 8.12.2
+ 9.0.1
- 1.0.8.RELEASE
- 0.14.4
- 2.18.0
- 1.5.1
- 1.18.0
- 2.35.1
+ 0.19.0
+ 2.23.1
+ 1.5.3
+ 1.20.0
+ 3.9.1spring.data.elasticsearch
@@ -132,9 +131,10 @@
+
org.elasticsearch.client
- elasticsearch-rest-client
+ elasticsearch-rest-client${elasticsearch-java}
@@ -144,6 +144,13 @@
+
+ com.querydsl
+ querydsl-core
+ ${querydsl}
+ true
+
+
com.fasterxml.jackson.core
@@ -248,13 +255,6 @@
test
-
- io.projectreactor.tools
- blockhound-junit-platform
- ${blockhound-junit}
- test
-
-
org.skyscreamerjsonassert
@@ -263,8 +263,8 @@
- com.github.tomakehurst
- wiremock-jre8
+ org.wiremock
+ wiremock${wiremock}test
@@ -443,25 +443,6 @@
-
- jdk13+
-
-
- [13,)
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- -XX:+AllowRedefinitionToAddDeleteMethods
-
-
-
-
-
-
antora-process-resources
@@ -479,7 +460,7 @@
- io.spring.maven.antora
+ org.antoraantora-maven-plugin
diff --git a/src/main/antora/antora-playbook.yml b/src/main/antora/antora-playbook.yml
index 27404c0c14..1a4f73c1e6 100644
--- a/src/main/antora/antora-playbook.yml
+++ b/src/main/antora/antora-playbook.yml
@@ -3,8 +3,7 @@
# The purpose of this Antora playbook is to build the docs in the current branch.
antora:
extensions:
- - '@antora/collector-extension'
- - require: '@springio/antora-extensions/root-component-extension'
+ - require: '@springio/antora-extensions'
root_component_name: 'data-elasticsearch'
site:
title: Spring Data Elasticsearch
@@ -18,17 +17,16 @@ content:
- url: https://github.com/spring-projects/spring-data-commons
# Refname matching:
# https://docs.antora.org/antora/latest/playbook/content-refname-matching/
- branches: [ main, 3.2.x ]
+ branches: [ main, 3.4.x, 3.3.x ]
start_path: src/main/antora
asciidoc:
attributes:
- page-pagination: ''
hide-uri-scheme: '@'
tabs-sync-option: '@'
- chomp: 'all'
extensions:
- '@asciidoctor/tabs'
- '@springio/asciidoctor-extensions'
+ - '@springio/asciidoctor-extensions/javadoc-extension'
sourcemap: true
urls:
latest_version_segment: ''
@@ -38,5 +36,5 @@ runtime:
format: pretty
ui:
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
diff --git a/src/main/antora/antora.yml b/src/main/antora/antora.yml
index 70364a772e..2348fca613 100644
--- a/src/main/antora/antora.yml
+++ b/src/main/antora/antora.yml
@@ -10,3 +10,8 @@ ext:
local: true
scan:
dir: target/classes/
+ - run:
+ command: ./mvnw package -Pdistribute
+ local: true
+ scan:
+ dir: target/antora
diff --git a/src/main/antora/modules/ROOT/nav.adoc b/src/main/antora/modules/ROOT/nav.adoc
index db6e1ca61b..fa1ee8110d 100644
--- a/src/main/antora/modules/ROOT/nav.adoc
+++ b/src/main/antora/modules/ROOT/nav.adoc
@@ -9,6 +9,10 @@
*** 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.1-5.2.adoc[]
+*** xref:migration-guides/migration-guide-5.2-5.3.adoc[]
+*** xref:migration-guides/migration-guide-5.3-5.4.adoc[]
+*** xref:migration-guides/migration-guide-5.4-5.5.adoc[]
+*** xref:migration-guides/migration-guide-5.5-6.0.adoc[]
* xref:elasticsearch.adoc[]
@@ -39,4 +43,5 @@
** xref:repositories/query-keywords-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]
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/auditing.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/auditing.adoc
index d02373f82b..f9633dec4f 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/auditing.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/auditing.adoc
@@ -10,7 +10,7 @@ In order for the auditing code to be able to decide whether an entity instance i
----
package org.springframework.data.domain;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
public interface Persistable {
@Nullable
@@ -81,5 +81,5 @@ class MyConfiguration {
}
----
-If your code contains more than one `AuditorAware` bean for different types, you must provide the name of the bean to use as an argument to the `auditorAwareRef` parameter of the
- `@EnableElasticsearchAuditing` annotation.
+If your code contains more than one `AuditorAware` bean for different types, you must provide the name of the bean to use as an argument to the `auditorAwareRef` parameter of the
+ `@EnableElasticsearchAuditing` annotation.
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/clients.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/clients.adoc
index 0f8d8c1027..0cf7d5ea3c 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/clients.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/clients.adoc
@@ -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]
====
-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:
@@ -52,13 +52,13 @@ RestClient restClient; <.>
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 low level `RestClient` from the Elasticsearch libraries
<.> 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.
[[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]
====
-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:
@@ -108,20 +108,20 @@ JsonpMapper jsonpMapper; <.>
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.
This is a reactive implementation based on the Elasticsearch client implementation.
<.> the low level `RestClient` from the Elasticsearch libraries
<.> 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.
[[elasticsearch.clients.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
====
@@ -178,7 +178,7 @@ If this is used in the reactive setup, the supplier function *must not* block!
[[elasticsearch.clients.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.
The following callbacks are provided:
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/elasticsearch-new.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/elasticsearch-new.adoc
index 17781c9946..f1e07dd195 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/elasticsearch-new.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/elasticsearch-new.adoc
@@ -1,15 +1,39 @@
[[new-features]]
= What's new
+[[new-features.6-0-0]]
+== New in Spring Data Elasticsearch 6.6
+
+* Upgarde to Spring 7
+* Switch to jspecify nullability annotations
+* Upgrade to Elasticsearch 9.0.1
+
+
+[[new-features.5-5-0]]
+== New in Spring Data Elasticsearch 5.5
+
+* Upgrade to Elasticsearch 8.18.1.
+* Add support for the `@SearchTemplateQuery` annotation on repository methods.
+* Scripted field properties of type collection can be populated from scripts returning arrays.
+
+[[new-features.5-4-0]]
+== New in Spring Data Elasticsearch 5.4
+
+* Upgrade to Elasticsearch 8.15.3.
+* Allow to customize the mapped type name for `@InnerField` and `@Field` annotations.
+* Support for Elasticsearch SQL.
+* Add support for retrieving request executionDuration.
+
[[new-features.5-3-0]]
== New in Spring Data Elasticsearch 5.3
-* Upgrade to Elasticsearch 8.12.2.
+* Upgrade to Elasticsearch 8.13.2.
* Add support for highlight queries in highlighting.
* Add shard statistics to the `SearchHit` class.
* Add support for multi search template API.
* Add support for SpEL in @Query.
* Add support for field aliases in the index mapping.
+* Add support for has_child and has_parent queries.
[[new-features.5-2-0]]
== New in Spring Data Elasticsearch 5.2
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/join-types.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/join-types.adoc
index c97dd46c62..a1bc3df192 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/join-types.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/join-types.adoc
@@ -52,7 +52,7 @@ public class Statement {
return routing;
}
- public void setRouting(Routing routing) {
+ public void setRouting(String routing) {
this.routing = routing;
}
@@ -199,7 +199,7 @@ void init() {
repository.save(
Statement.builder()
.withText("+1 for the sun")
- ,withRouting(savedWeather.getId())
+ .withRouting(savedWeather.getId())
.withRelation(new JoinField<>("vote", sunnyAnswer.getId())) <5>
.build());
}
@@ -226,6 +226,7 @@ SearchHits hasVotes() {
Query query = NativeQuery.builder()
.withQuery(co.elastic.clients.elasticsearch._types.query_dsl.Query.of(qb -> qb
.hasChild(hc -> hc
+ .type("answer")
.queryName("vote")
.query(matchAllQueryAsQuery())
.scoreMode(ChildScoreMode.None)
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/misc.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/misc.adoc
index 36567cda4a..7f3ac8f0ff 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/misc.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/misc.adoc
@@ -365,6 +365,8 @@ operations.putScript( <.>
To use a search template in a search query, Spring Data Elasticsearch provides the `SearchTemplateQuery`, an implementation of the `org.springframework.data.elasticsearch.core.query.Query` interface.
+NOTE: Although `SearchTemplateQuery` is an implementation of the `Query` interface, not all of the functionality provided by the base class is available for a `SearchTemplateQuery` like setting a `Pageable` or a `Sort`. Values for this functionality must be added to the stored script like shown in the following example for paging parameters. If these values are set on the `Query` object, they will be ignored.
+
In the following code, we will add a call using a search template query to a custom repository implementation (see
xref:repositories/custom-implementations.adoc[]) as an example how this can be integrated into a repository call.
@@ -449,4 +451,3 @@ var query = Query.findAll().addSort(Sort.by(order));
About the filter query: It is not possible to use a `CriteriaQuery` here, as this query would be converted into a Elasticsearch nested query which does not work in the filter context. So only `StringQuery` or `NativeQuery` can be used here. When using one of these, like the term query above, the Elasticsearch field names must be used, so take care, when these are redefined with the `@Field(name="...")` definition.
For the definition of the order path and the nested paths, the Java entity property names should be used.
-
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/object-mapping.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/object-mapping.adoc
index ab6e98d5c4..6ca12728c0 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/object-mapping.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/object-mapping.adoc
@@ -192,8 +192,7 @@ public String getProperty() {
This annotation can be set on a String property of an entity.
This property will not be written to the mapping, it will not be stored in Elasticsearch and its value will not be read from an Elasticsearch document.
-After an entity is persisted, for example with a call to `ElasticsearchOperations.save(T entity)`, the entity
-returned from that call will contain the name of the index that an entity was saved to in that property.
+After an entity is persisted, for example with a call to `ElasticsearchOperations.save(T entity)`, the entity returned from that call will contain the name of the index that an entity was saved to in that property.
This is useful when the index name is dynamically set by a bean, or when writing to a write alias.
Putting some value into such a property does not set the index into which an entity is stored!
@@ -423,7 +422,6 @@ Looking at the `Configuration` from the xref:elasticsearch/object-mapping.adoc#e
@Configuration
public class Config extends ElasticsearchConfiguration {
- @NonNull
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder() //
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/repositories/elasticsearch-repository-queries.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/repositories/elasticsearch-repository-queries.adoc
index b558e13bba..b22e17522d 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/repositories/elasticsearch-repository-queries.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/repositories/elasticsearch-repository-queries.adoc
@@ -10,7 +10,9 @@ 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 use of the `@Query` annotation (see xref:elasticsearch/repositories/elasticsearch-repository-queries.adoc#elasticsearch.query-methods.at-query[Using @Query Annotation] ).
+In this case one might make use of the `@Query` annotation (see xref:elasticsearch/repositories/elasticsearch-repository-queries.adoc#elasticsearch.query-methods.at-query[Using the @Query Annotation] ).
+
+Another possibility is the use of a search-template, (see xref:elasticsearch/repositories/elasticsearch-repository-queries.adoc#elasticsearch.query-methods.at-searchtemplate-query[Using the @SearchTemplateQuery Annotation] ).
[[elasticsearch.query-methods.criterions]]
== Query creation
@@ -312,11 +314,13 @@ Repository methods can be defined to have the following return types for returni
* `SearchPage`
[[elasticsearch.query-methods.at-query]]
-== Using @Query Annotation
+== Using the @Query Annotation
.Declare query on the method using the `@Query` annotation.
====
-The arguments passed to the method can be inserted into placeholders in the query string. The placeholders are of the form `?0`, `?1`, `?2` etc. for the first, second, third parameter and so on.
+The arguments passed to the method can be inserted into placeholders in the query string.
+The placeholders are of the form `?0`, `?1`, `?2` etc. for the first, second, third parameter and so on.
+
[source,java]
----
interface BookRepository extends ElasticsearchRepository {
@@ -341,15 +345,20 @@ It will be sent to Easticsearch as value of the query element; if for example th
}
----
====
+
.`@Query` annotation on a method taking a Collection argument
====
A repository method such as
+
[source,java]
----
@Query("{\"ids\": {\"values\": ?0 }}")
List getByIds(Collection ids);
----
-would make an https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html[IDs query] to return all the matching documents. So calling the method with a `List` of `["id1", "id2", "id3"]` would produce the query body
+
+would make an https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html[IDs query] to return all the matching documents.
+So calling the method with a `List` of `["id1", "id2", "id3"]` would produce the query body
+
[source,json]
----
{
@@ -369,7 +378,6 @@ would make an https://www.elastic.co/guide/en/elasticsearch/reference/current/qu
====
https://docs.spring.io/spring-framework/reference/core/expressions.html[SpEL expression] is also supported when defining query in `@Query`.
-
[source,java]
----
interface BookRepository extends ElasticsearchRepository {
@@ -411,6 +419,7 @@ If for example the function is called with the parameter _John_, it would produc
.accessing parameter property.
====
Supposing that we have the following class as query parameter type:
+
[source,java]
----
public record QueryParameter(String value) {
@@ -444,7 +453,9 @@ We can pass `new QueryParameter("John")` as the parameter now, and it will produ
.accessing bean property.
====
-https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/bean-references.html[Bean property] is also supported to access. Given that there is a bean named `queryParameter` of type `QueryParameter`, we can access the bean with symbol `@` rather than `#`, and there is no need to declare a parameter of type `QueryParameter` in the query method:
+https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/bean-references.html[Bean property] is also supported to access.
+Given that there is a bean named `queryParameter` of type `QueryParameter`, we can access the bean with symbol `@` rather than `#`, and there is no need to declare a parameter of type `QueryParameter` in the query method:
+
[source,java]
----
interface BookRepository extends ElasticsearchRepository {
@@ -493,6 +504,7 @@ interface BookRepository extends ElasticsearchRepository {
NOTE: collection values should not be quoted when declaring the elasticsearch json query.
A collection of `names` like `List.of("name1", "name2")` will produce the following terms query:
+
[source,json]
----
{
@@ -532,6 +544,7 @@ interface BookRepository extends ElasticsearchRepository {
Page findByName(Collection parameters, Pageable pageable);
}
----
+
This will extract all the `value` property values as a new `Collection` from `QueryParameter` collection, thus takes the same effect as above.
====
@@ -560,3 +573,20 @@ interface BookRepository extends ElasticsearchRepository {
----
====
+
+[[elasticsearch.query-methods.at-searchtemplate-query]]
+== Using the @SearchTemplateQuery Annotation
+
+When using Elasticsearch search templates - (see xref:elasticsearch/misc.adoc#elasticsearch.misc.searchtemplates [Search Template support]) it is possible to specify that a repository method should use a template by adding the `@SearchTemplateQuery` annotation to that method.
+
+Let's assume that there is a search template stored with the name "book-by-title" and this template need a parameter named "title", then a repository method using that search template can be defined like this:
+
+[source,java]
+----
+interface BookRepository extends ElasticsearchRepository {
+ @SearchTemplateQuery(id = "book-by-title")
+ SearchHits findByTitle(String title);
+}
+----
+
+The parameters of the repository method are sent to the seacrh template as key/value pairs where the key is the parameter name and the value is taken from the actual value when the method is invoked.
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/scripted-and-runtime-fields.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/scripted-and-runtime-fields.adoc
index 7c5d730e25..64d4a0c003 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/scripted-and-runtime-fields.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/scripted-and-runtime-fields.adoc
@@ -20,12 +20,12 @@ Whereas the birthdate is fix, the age depends on the time when a query is issued
====
[source,java]
----
+import org.jspecify.annotations.Nullable;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.ScriptedField;
-import org.springframework.lang.Nullable;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@@ -194,7 +194,7 @@ In the following code this is used to run a query for a given gender and maximum
var runtimeField = new RuntimeField("age", "long", """ <.>
Instant currentDate = Instant.ofEpochMilli(new Date().getTime());
- Instant startDate = doc['birth-date'].value.toInstant();
+ Instant startDate = doc['birthDate'].value.toInstant();
emit (ChronoUnit.DAYS.between(startDate, currentDate) / 365);
""");
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/template.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/template.adoc
index b893bb1a19..d5cbec5d09 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/template.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/template.adoc
@@ -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[]).
-* `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.
-* `SearchOperations` define the actions to search for multiple entities using queries
-* `ElasticsearchOperations` combines the `DocumentOperations` and `SearchOperations` interfaces.
+* javadoc:org.springframework.data.elasticsearch.core.IndexOperations[] defines actions on index level like creating or deleting an index.
+* javadoc:org.springframework.data.elasticsearch.core.DocumentOperations[] defines actions to store, update and retrieve entities based on their id.
+* javadoc:org.springframework.data.elasticsearch.core.SearchOperations[] define the actions to search for multiple entities using queries
+* 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].
@@ -81,7 +81,7 @@ When a document is retrieved with the methods of the `DocumentOperations` inter
When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity.
In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information.
-These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations.
+These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations or the execution duration it took to complete the request.
The following classes and interfaces are now available:
.SearchHit
diff --git a/src/main/antora/modules/ROOT/pages/elasticsearch/versions.adoc b/src/main/antora/modules/ROOT/pages/elasticsearch/versions.adoc
index 9f88a81734..8fb6d72617 100644
--- a/src/main/antora/modules/ROOT/pages/elasticsearch/versions.adoc
+++ b/src/main/antora/modules/ROOT/pages/elasticsearch/versions.adoc
@@ -6,10 +6,13 @@ The following table shows the Elasticsearch and Spring versions that are used by
[cols="^,^,^,^",options="header"]
|===
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
-| 2024.0 (?) | 5.3.x | 8.12.2 | ?
-| 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.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
+| 2025.1 (in development) | 6.0.x | 9.0.1 | 7.0.x
+| 2025.0 | 5.5.x | 8.18.1 | 6.2.x
+| 2024.1 | 5.4.x | 8.15.5 | 6.1.x
+| 2024.0 | 5.3.xfootnote:oom[Out of maintenance] | 8.13.4 | 6.1.x
+| 2023.1 (Vaughan) | 5.2.xfootnote:oom[] | 8.11.1 | 6.1.x
+| 2023.0 (Ullmann) | 5.1.xfootnote:oom[] | 8.7.1 | 6.0.x
+| 2022.0 (Turing) | 5.0.xfootnote:oom[] | 8.5.3 | 6.0.x
| 2021.2 (Raj) | 4.4.xfootnote:oom[] | 7.17.3 | 5.3.x
| 2021.1 (Q) | 4.3.xfootnote:oom[] | 7.15.2 | 5.3.x
| 2021.0 (Pascal) | 4.2.xfootnote:oom[] | 7.12.0 | 5.3.x
diff --git a/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.2-5.3.adoc b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.2-5.3.adoc
index 17ab9063c5..808578cb59 100644
--- a/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.2-5.3.adoc
+++ b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.2-5.3.adoc
@@ -6,10 +6,16 @@ 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]]
== 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]]
== Deprecations
=== Removals
+
The deprecated classes `org.springframework.data.elasticsearch.ELCQueries`
- and `org.springframework.data.elasticsearch.client.elc.QueryBuilders` have been removed, use `org.springframework.data.elasticsearch.client.elc.Queries` instead.
+and `org.springframework.data.elasticsearch.client.elc.QueryBuilders` have been removed, use `org.springframework.data.elasticsearch.client.elc.Queries` instead.
diff --git a/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.3-5.4.adoc b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.3-5.4.adoc
new file mode 100644
index 0000000000..c5178ff75d
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.3-5.4.adoc
@@ -0,0 +1,23 @@
+[[elasticsearch-migration-guide-5.3-5.4]]
+= Upgrading from 5.3.x to 5.4.x
+
+This section describes breaking changes from version 5.3.x to 5.4.x and how removed features can be replaced by new introduced features.
+
+[[elasticsearch-migration-guide-5.3-5.4.breaking-changes]]
+== Breaking Changes
+
+[[elasticsearch-migration-guide-5.3-5.4.breaking-changes.knn-search]]
+=== knn search
+The `withKnnQuery` method in `NativeQueryBuilder` has been replaced with `withKnnSearches` to build a `NativeQuery` with knn search.
+
+`KnnQuery` and `KnnSearch` are two different classes in elasticsearch java client and are used for different queries, with different parameters supported:
+
+- `KnnSearch`: is https://www.elastic.co/guide/en/elasticsearch/reference/8.13/search-search.html#search-api-knn[the top level `knn` query] in the elasticsearch request;
+- `KnnQuery`: is https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-knn-query.html[the `knn` query inside `query` clause];
+
+If `KnnQuery` is still preferable, please be sure to construct it inside `query` clause manually, by means of `withQuery(co.elastic.clients.elasticsearch._types.query_dsl.Query query)` clause in `NativeQueryBuilder`.
+
+[[elasticsearch-migration-guide-5.3-5.4.deprecations]]
+== Deprecations
+
+=== Removals
diff --git a/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.4-5.5.adoc b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.4-5.5.adoc
new file mode 100644
index 0000000000..38b2b4af2b
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.4-5.5.adoc
@@ -0,0 +1,30 @@
+[[elasticsearch-migration-guide-5.4-5.5]]
+= Upgrading from 5.4.x to 5.5.x
+
+This section describes breaking changes from version 5.4.x to 5.5.x and how removed features can be replaced by new introduced features.
+
+[[elasticsearch-migration-guide-5.4-5.5.breaking-changes]]
+== Breaking Changes
+
+[[elasticsearch-migration-guide-5.4-5.5.deprecations]]
+== Deprecations
+
+Some classes that probably are not used by a library user have been renamed, the classes with the old names are still there, but are deprecated:
+
+|===
+|old name|new name
+
+|ElasticsearchPartQuery|RepositoryPartQuery
+|ElasticsearchStringQuery|RepositoryStringQuery
+|ReactiveElasticsearchStringQuery|ReactiveRepositoryStringQuery
+|===
+
+=== Removals
+
+The following methods that had been deprecated since release 5.3 have been removed:
+```
+DocumentOperations.delete(Query, Class>)
+DocumentOperations.delete(Query, Class>, IndexCoordinates)
+ReactiveDocumentOperations.delete(Query, Class>)
+ReactiveDocumentOperations.delete(Query, Class>, IndexCoordinates)
+```
diff --git a/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.5-6.0.adoc b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.5-6.0.adoc
new file mode 100644
index 0000000000..7667701a17
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/migration-guides/migration-guide-5.5-6.0.adoc
@@ -0,0 +1,21 @@
+[[elasticsearch-migration-guide-5.5-6.0]]
+= Upgrading from 5.5.x to 6.0.x
+
+This section describes breaking changes from version 5.5.x to 6.0.x and how removed features can be replaced by new introduced features.
+
+[[elasticsearch-migration-guide-5.5-6.0.breaking-changes]]
+== Breaking Changes
+
+[[elasticsearch-migration-guide-5.5-6.0.deprecations]]
+== Deprecations
+
+
+=== Removals
+
+The `org.springframework.data.elasticsearch.core.query.ScriptType` enum has been removed. To distinguish between an inline and a stored script set the appropriate values in the `org.springframework.data.elasticsearch.core.query.ScriptData` record.
+
+These methods have been removed because the Elasticsearch Client 9 does not support them anymore:
+```
+org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchIndicesClient.unfreeze(UnfreezeRequest)
+org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchIndicesClient.unfreeze(Function>)
+```
diff --git a/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java b/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java
index 9308caa924..6d40bca631 100644
--- a/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchErrorCause.java b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchErrorCause.java
index 130f218f8f..22dbbfd7c0 100644
--- a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchErrorCause.java
+++ b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchErrorCause.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
@@ -15,10 +15,10 @@
*/
package org.springframework.data.elasticsearch;
-import org.springframework.lang.Nullable;
-
import java.util.List;
+import org.jspecify.annotations.Nullable;
+
/**
* Object describing an Elasticsearch error
*
@@ -26,8 +26,7 @@
* @since 4.4
*/
public class ElasticsearchErrorCause {
- @Nullable
- private final String type;
+ @Nullable private final String type;
private final String reason;
diff --git a/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java b/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java
index a431801aa4..c1eab9bcf7 100644
--- a/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 the original author or authors.
+ * Copyright 2019-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/ResourceFailureException.java b/src/main/java/org/springframework/data/elasticsearch/ResourceFailureException.java
index 8dac09e1dc..493d3b4b7b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/ResourceFailureException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/ResourceFailureException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/ResourceNotFoundException.java b/src/main/java/org/springframework/data/elasticsearch/ResourceNotFoundException.java
index 5ba76a6b29..5e97b4e00b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/ResourceNotFoundException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/ResourceNotFoundException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/RestStatusException.java b/src/main/java/org/springframework/data/elasticsearch/RestStatusException.java
index b743cc794f..c707686098 100644
--- a/src/main/java/org/springframework/data/elasticsearch/RestStatusException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/RestStatusException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java
index c04de263ee..ffc71ef7ba 100644
--- a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -15,8 +15,8 @@
*/
package org.springframework.data.elasticsearch;
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.UncategorizedDataAccessException;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/main/java/org/springframework/data/elasticsearch/VersionConflictException.java b/src/main/java/org/springframework/data/elasticsearch/VersionConflictException.java
index ea02677529..b3f31d3550 100644
--- a/src/main/java/org/springframework/data/elasticsearch/VersionConflictException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/VersionConflictException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 the original author or authors.
+ * Copyright 2023-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Alias.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Alias.java
new file mode 100644
index 0000000000..0f707e942e
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Alias.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.core.annotation.AliasFor;
+
+/**
+ * Identifies an alias for the index.
+ *
+ * @author Youssef Aouichaoui
+ * @since 5.4
+ */
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE })
+@Repeatable(Aliases.class)
+public @interface Alias {
+ /**
+ * @return Index alias name. Alias for {@link #alias}.
+ */
+ @AliasFor("alias")
+ String value() default "";
+
+ /**
+ * @return Index alias name. Alias for {@link #value}.
+ */
+ @AliasFor("value")
+ String alias() default "";
+
+ /**
+ * @return Query used to limit documents the alias can access.
+ */
+ Filter filter() default @Filter;
+
+ /**
+ * @return Used to route indexing operations to a specific shard.
+ */
+ String indexRouting() default "";
+
+ /**
+ * @return Used to route indexing and search operations to a specific shard.
+ */
+ String routing() default "";
+
+ /**
+ * @return Used to route search operations to a specific shard.
+ */
+ String searchRouting() default "";
+
+ /**
+ * @return Is the alias hidden?
+ */
+ boolean isHidden() default false;
+
+ /**
+ * @return Is it the 'write index' for the alias?
+ */
+ boolean isWriteIndex() default false;
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Aliases.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Aliases.java
new file mode 100644
index 0000000000..ea5d895294
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Aliases.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Container annotation that aggregates several {@link Alias} annotations.
+ *
+ * @author Youssef Aouichaoui
+ * @see Alias
+ * @since 5.4
+ */
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE })
+public @interface Aliases {
+ Alias[] value();
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java
index 3d93be01ec..da27c1245b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 the original author or authors.
+ * Copyright 2019-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java
index 04401340d8..94ca1ea724 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2024 the original author or authors.
+ * Copyright 2013-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/CountQuery.java b/src/main/java/org/springframework/data/elasticsearch/annotations/CountQuery.java
index 0a0e80752b..80bb7c15f9 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/CountQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/CountQuery.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java
index 4e48e567a1..9f3b7f9d78 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2024 the original author or authors.
+ * Copyright 2014-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java
index 391e303e06..1131b2cd59 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2024 the original author or authors.
+ * Copyright 2013-2025 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.
@@ -100,6 +100,13 @@
*/
boolean storeVersionInSource() default true;
+ /**
+ * Aliases for the index.
+ *
+ * @since 5.4
+ */
+ Alias[] aliases() default {};
+
/**
* @since 4.3
*/
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Dynamic.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Dynamic.java
index 23a82f384b..9868c6e3c6 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Dynamic.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Dynamic.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java
index dd299a4930..97815477ae 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2024 the original author or authors.
+ * Copyright 2013-2025 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.
@@ -37,6 +37,8 @@
* @author Brian Kimmig
* @author Morgan Lutz
* @author Sascha Woo
+ * @author Haibo Liu
+ * @author Andriy Redko
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@@ -128,6 +130,10 @@
boolean norms() default true;
/**
+ * NOte that null_value setting are not supported in Elasticsearch for all types. For example setting a null_value on
+ * a field with type text will throw an exception in the server when the mapping is written to Elasticsearch. Alas,
+ * the Elasticsearch documentation does not specify on which types it is allowed on which it is not.
+ *
* @since 4.0
*/
String nullValue() default "";
@@ -195,6 +201,27 @@
*/
int dims() default -1;
+ /**
+ * to be used in combination with {@link FieldType#Dense_Vector}
+ *
+ * @since 5.4
+ */
+ String elementType() default FieldElementType.DEFAULT;
+
+ /**
+ * to be used in combination with {@link FieldType#Dense_Vector}
+ *
+ * @since 5.4
+ */
+ KnnSimilarity knnSimilarity() default KnnSimilarity.DEFAULT;
+
+ /**
+ * to be used in combination with {@link FieldType#Dense_Vector}
+ *
+ * @since 5.4
+ */
+ KnnIndexOptions[] knnIndexOptions() default {};
+
/**
* Controls how Elasticsearch dynamically adds fields to the inner object within the document.
* To be used in combination with {@link FieldType#Object} or {@link FieldType#Nested}
@@ -218,4 +245,11 @@
* @since 5.1
*/
boolean storeEmptyValue() default true;
+
+ /**
+ * overrides the field type in the mapping which otherwise will be taken from corresponding {@link FieldType}
+ *
+ * @since 5.4
+ */
+ String mappedTypeName() default "";
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldElementType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldElementType.java
new file mode 100644
index 0000000000..49271764ba
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldElementType.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+/**
+ * @author Haibo Liu
+ * @since 5.4
+ */
+public final class FieldElementType {
+ public final static String DEFAULT = "";
+ public final static String FLOAT = "float";
+ public final static String BYTE = "byte";
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java
index f148efb638..f701948d6d 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2024 the original author or authors.
+ * Copyright 2013-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Filter.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Filter.java
new file mode 100644
index 0000000000..7f07df55d1
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Filter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+import org.springframework.core.annotation.AliasFor;
+
+/**
+ * Query used to limit documents.
+ *
+ * @author Youssef Aouichaoui
+ * @since 5.4
+ */
+public @interface Filter {
+ /**
+ * @return Query used to limit documents. Alias for {@link #query}.
+ */
+ @AliasFor("query")
+ String value() default "";
+
+ /**
+ * @return Query used to limit documents. Alias for {@link #value}.
+ */
+ @AliasFor("value")
+ String query() default "";
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java
index 7feda38237..05695abc98 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2024 the original author or authors.
+ * Copyright 2013-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/GeoShapeField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/GeoShapeField.java
index 0a3be4d2d6..0121b07ee1 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/GeoShapeField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/GeoShapeField.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2024 the original author or authors.
+ * Copyright 2017-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java
index 3b93f232d6..30312ab434 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java
index 73063b3451..f6318be98a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java
index 530c813ca5..d4e8bbfd2b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java
index 89637309a9..2de226c7b1 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 the original author or authors.
+ * Copyright 2019-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java
index 76a481f735..01adc8fbb4 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 the original author or authors.
+ * Copyright 2019-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java
index fd8cc8146a..4d76b97492 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 the original author or authors.
+ * Copyright 2023-2025 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.
@@ -15,9 +15,6 @@
*/
package org.springframework.data.elasticsearch.annotations;
-import org.springframework.data.annotation.ReadOnlyProperty;
-import org.springframework.data.annotation.Transient;
-
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -25,10 +22,10 @@
import java.lang.annotation.Target;
/**
- * Annotation to mark a String property of an entity to be filled with the name of the index where the entity was
- * stored after it is indexed into Elasticsearch. This can be used when the name of the index is dynamically created
- * or when a document was indexed into a write alias.
- *
+ * Annotation to mark a String property of an entity to be filled with the name of the index where the entity was stored
+ * after it is indexed into Elasticsearch. This can be used when the name of the index is dynamically created or when a
+ * document was indexed into a write alias.
+ *
* This can not be used to specify the index where an entity should be written to.
*
* @author Peter-Josef Meisch
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java
index ceb6054119..651bf5a825 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2024 the original author or authors.
+ * Copyright 2014-2025 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.
@@ -29,6 +29,8 @@
* @author Aleksei Arsenev
* @author Brian Kimmig
* @author Morgan Lutz
+ * @author Haibo Liu
+ * @author Andriy Redko
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
@@ -149,4 +151,32 @@
* @since 4.2
*/
int dims() default -1;
+
+ /**
+ * to be used in combination with {@link FieldType#Dense_Vector}
+ *
+ * @since 5.4
+ */
+ String elementType() default FieldElementType.DEFAULT;
+
+ /**
+ * to be used in combination with {@link FieldType#Dense_Vector}
+ *
+ * @since 5.4
+ */
+ KnnSimilarity knnSimilarity() default KnnSimilarity.DEFAULT;
+
+ /**
+ * to be used in combination with {@link FieldType#Dense_Vector}
+ *
+ * @since 5.4
+ */
+ KnnIndexOptions[] knnIndexOptions() default {};
+
+ /**
+ * overrides the field type in the mapping which otherwise will be taken from corresponding {@link FieldType}
+ *
+ * @since 5.4
+ */
+ String mappedTypeName() default "";
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java
index 4e544bd4c4..eb2e1e4623 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java
index fb1be2b68c..2004200cf2 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/KnnAlgorithmType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/KnnAlgorithmType.java
new file mode 100644
index 0000000000..6110e54be8
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/KnnAlgorithmType.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+/**
+ * @author Haibo Liu
+ * @since 5.4
+ */
+public enum KnnAlgorithmType {
+ HNSW("hnsw"),
+ INT8_HNSW("int8_hnsw"),
+ FLAT("flat"),
+ INT8_FLAT("int8_flat"),
+ DEFAULT("");
+
+ private final String type;
+
+ KnnAlgorithmType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/KnnIndexOptions.java b/src/main/java/org/springframework/data/elasticsearch/annotations/KnnIndexOptions.java
new file mode 100644
index 0000000000..56d871d3b5
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/KnnIndexOptions.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+/**
+ * @author Haibo Liu
+ * @since 5.4
+ */
+public @interface KnnIndexOptions {
+
+ KnnAlgorithmType type() default KnnAlgorithmType.DEFAULT;
+
+ /**
+ * Only applicable to {@link KnnAlgorithmType#HNSW} and {@link KnnAlgorithmType#INT8_HNSW} index types.
+ */
+ int m() default -1;
+
+ /**
+ * Only applicable to {@link KnnAlgorithmType#HNSW} and {@link KnnAlgorithmType#INT8_HNSW} index types.
+ */
+ int efConstruction() default -1;
+
+ /**
+ * Only applicable to {@link KnnAlgorithmType#INT8_HNSW} and {@link KnnAlgorithmType#INT8_FLAT} index types.
+ */
+ float confidenceInterval() default -1F;
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/KnnSimilarity.java b/src/main/java/org/springframework/data/elasticsearch/annotations/KnnSimilarity.java
new file mode 100644
index 0000000000..d03c42a6fd
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/KnnSimilarity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024-2025 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.annotations;
+
+/**
+ * @author Haibo Liu
+ * @since 5.4
+ */
+public enum KnnSimilarity {
+ L2_NORM("l2_norm"),
+ DOT_PRODUCT("dot_product"),
+ COSINE("cosine"),
+ MAX_INNER_PRODUCT("max_inner_product"),
+ DEFAULT("");
+
+ private final String similarity;
+
+ KnnSimilarity(String similarity) {
+ this.similarity = similarity;
+ }
+
+ public String getSimilarity() {
+ return similarity;
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java
index 0fd36357df..c2d48c3884 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2024 the original author or authors.
+ * Copyright 2014-2025 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.
@@ -82,6 +82,6 @@
MappingAlias[] aliases() default {};
enum Detection {
- DEFAULT, TRUE, FALSE;
+ DEFAULT, TRUE, FALSE
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/MappingAlias.java b/src/main/java/org/springframework/data/elasticsearch/annotations/MappingAlias.java
index f71e664ee2..791659e9d5 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/MappingAlias.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/MappingAlias.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 the original author or authors.
+ * Copyright 2024-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java
index 1523cd88ba..9dff38c1f1 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2024 the original author or authors.
+ * Copyright 2014-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/NullValueType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/NullValueType.java
index 8707def774..a131b12a8e 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/NullValueType.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/NullValueType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java
index f5746a3551..9f1b755c35 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2024 the original author or authors.
+ * Copyright 2013-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/SearchTemplateQuery.java b/src/main/java/org/springframework/data/elasticsearch/annotations/SearchTemplateQuery.java
new file mode 100644
index 0000000000..f50675d979
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/SearchTemplateQuery.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 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.annotations;
+
+import org.springframework.data.annotation.QueryAnnotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to mark a repository method as a search template method. The annotation defines the search template id,
+ * the parameters for the search template are taken from the method's arguments.
+ *
+ * @author P.J. Meisch (pj.meisch@sothawo.com)
+ * @since 5.5
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
+@Documented
+@QueryAnnotation
+public @interface SearchTemplateQuery {
+ /**
+ * The id of the search template. Must not be empt or null.
+ */
+ String id();
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java
index 51f31b3b25..926154f1f2 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2024 the original author or authors.
+ * Copyright 2014-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java
index 143996ea54..46cafd91a2 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 the original author or authors.
+ * Copyright 2019-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/SourceFilters.java b/src/main/java/org/springframework/data/elasticsearch/annotations/SourceFilters.java
index 73f434999a..055ecc616f 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/SourceFilters.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/SourceFilters.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java b/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java
index 377ed9063a..25de2cbcad 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 the original author or authors.
+ * Copyright 2019-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/ValueConverter.java b/src/main/java/org/springframework/data/elasticsearch/annotations/ValueConverter.java
index 5e07262799..eb848bfed2 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/ValueConverter.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/ValueConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
@@ -41,7 +41,7 @@
* Defines the class implementing the {@link PropertyValueConverter} interface. If this is a normal class, it must
* provide a default constructor with no arguments. If this is an enum and thus implementing a singleton by enum it
* must only have one enum value.
- *
+ *
* @return the class to use for conversion
*/
Class extends PropertyValueConverter> value();
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/WriteOnlyProperty.java b/src/main/java/org/springframework/data/elasticsearch/annotations/WriteOnlyProperty.java
index 12ca0e1d22..7704450e26 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/WriteOnlyProperty.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/WriteOnlyProperty.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/WriteTypeHint.java b/src/main/java/org/springframework/data/elasticsearch/annotations/WriteTypeHint.java
index d62a704b7c..86a844cc18 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/WriteTypeHint.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/WriteTypeHint.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java b/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java
index 60fe252678..4b8ccdf64e 100644
--- a/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.annotations;
diff --git a/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java b/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java
index e751a40237..c3921b8940 100644
--- a/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java
+++ b/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 the original author or authors.
+ * Copyright 2023-2025 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.
@@ -25,11 +25,11 @@
*/
public class ElasticsearchAotPredicates {
- public static final Predicate IS_REACTIVE_LIBARARY_AVAILABLE = (
+ public static final Predicate IS_REACTIVE_LIBRARY_AVAILABLE = (
lib) -> ReactiveWrappers.isAvailable(lib);
public static boolean isReactorPresent() {
- return IS_REACTIVE_LIBARARY_AVAILABLE.test(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR);
+ return IS_REACTIVE_LIBRARY_AVAILABLE.test(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR);
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/aot/SpringDataElasticsearchRuntimeHints.java b/src/main/java/org/springframework/data/elasticsearch/aot/SpringDataElasticsearchRuntimeHints.java
index 0dfbb146fa..100b2ae449 100644
--- a/src/main/java/org/springframework/data/elasticsearch/aot/SpringDataElasticsearchRuntimeHints.java
+++ b/src/main/java/org/springframework/data/elasticsearch/aot/SpringDataElasticsearchRuntimeHints.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 the original author or authors.
+ * Copyright 2023-2025 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.
@@ -19,6 +19,7 @@
import java.util.Arrays;
+import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -32,7 +33,6 @@
import org.springframework.data.elasticsearch.core.event.ReactiveAfterLoadCallback;
import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback;
import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java b/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java
index 292bf8a1a1..56697c1029 100644
--- a/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.aot;
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java
index ddc0710263..f092e2bf6b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 the original author or authors.
+ * Copyright 2018-2025 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.
@@ -25,8 +25,8 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.support.HttpHeaders;
-import org.springframework.lang.Nullable;
/**
* Configuration interface exposing common client configuration properties for Elasticsearch clients.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java
index 2eb55b7702..71af992127 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 the original author or authors.
+ * Copyright 2018-2025 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.
@@ -25,11 +25,11 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithRequiredEndpoint;
import org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder;
import org.springframework.data.elasticsearch.client.ClientConfiguration.TerminalClientConfigurationBuilder;
import org.springframework.data.elasticsearch.support.HttpHeaders;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java
index e5f50ed0e4..ea097bbb59 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 the original author or authors.
+ * Copyright 2018-2025 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.
@@ -24,9 +24,8 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
-import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.support.HttpHeaders;
-import org.springframework.lang.Nullable;
/**
* Default {@link ClientConfiguration} implementation.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java b/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java
index f422ecded2..014acb6328 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 the original author or authors.
+ * Copyright 2018-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java b/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java
index e5d9cd1f2d..33f71a49ed 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 the original author or authors.
+ * Copyright 2018-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java b/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java
index 2487768785..b8a560db63 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 the original author or authors.
+ * Copyright 2018-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedBackendOperation.java b/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedBackendOperation.java
index 1268ff3262..0264b95c00 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedBackendOperation.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedBackendOperation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedClientOperationException.java b/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedClientOperationException.java
index 112a03c783..322646bc66 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedClientOperationException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/UnsupportedClientOperationException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/AbstractQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/AbstractQueryProcessor.java
new file mode 100644
index 0000000000..ff0e1bd3a0
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/AbstractQueryProcessor.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2024-2025 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.client.elc;
+
+import java.util.function.Consumer;
+
+import org.jspecify.annotations.Nullable;
+import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
+import org.springframework.data.elasticsearch.core.query.Query;
+import org.springframework.data.elasticsearch.core.query.StringQuery;
+
+/**
+ * An abstract class that serves as a base for query processors. It provides a common interface and basic functionality
+ * for query processing.
+ *
+ * @author Aouichaoui Youssef
+ * @since 5.3
+ */
+public abstract class AbstractQueryProcessor {
+
+ /**
+ * Convert a spring-data-elasticsearch {@literal query} to an Elasticsearch {@literal query}.
+ *
+ * @param query spring-data-elasticsearch {@literal query}.
+ * @param queryConverter correct mapped field names and the values to the converted values.
+ * @return an Elasticsearch {@literal query}.
+ */
+
+ static co.elastic.clients.elasticsearch._types.query_dsl.@Nullable Query getEsQuery(@Nullable Query query,
+ @Nullable Consumer queryConverter) {
+ if (query == null) {
+ return null;
+ }
+
+ if (queryConverter != null) {
+ queryConverter.accept(query);
+ }
+
+ co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = null;
+
+ if (query instanceof CriteriaQuery criteriaQuery) {
+ esQuery = CriteriaQueryProcessor.createQuery(criteriaQuery.getCriteria());
+ } else if (query instanceof StringQuery stringQuery) {
+ esQuery = Queries.wrapperQueryAsQuery(stringQuery.getSource());
+ } else if (query instanceof NativeQuery nativeQuery) {
+ if (nativeQuery.getQuery() != null) {
+ esQuery = nativeQuery.getQuery();
+ } else if (nativeQuery.getSpringDataQuery() != null) {
+ esQuery = getEsQuery(nativeQuery.getSpringDataQuery(), queryConverter);
+ }
+ } else {
+ throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName());
+ }
+
+ return esQuery;
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/Aggregation.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/Aggregation.java
index ab46cad895..23e2b6ae47 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/Aggregation.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/Aggregation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 the original author or authors.
+ * Copyright 2022-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java
index d6489ba19c..3ce661e1fd 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
@@ -16,9 +16,10 @@
package org.springframework.data.elasticsearch.client.elc;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
-import co.elastic.clients.elasticsearch.cluster.ElasticsearchClusterClient;
import co.elastic.clients.transport.ElasticsearchTransport;
+import java.io.IOException;
+
import org.elasticsearch.client.RestClient;
import org.springframework.util.Assert;
@@ -37,12 +38,10 @@ public AutoCloseableElasticsearchClient(ElasticsearchTransport transport) {
}
@Override
- public void close() throws Exception {
- transport.close();
- }
-
- @Override
- public ElasticsearchClusterClient cluster() {
- return super.cluster();
+ public void close() throws IOException {
+ // since Elasticsearch 8.16 the ElasticsearchClient implements (through ApiClient) the Closeable interface and
+ // handles closing of the underlying transport. We now just call the base class, but keep this as we
+ // have been implementing AutoCloseable since 4.4 and won't change that to a mere Closeable
+ super.close();
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/ChildTemplate.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/ChildTemplate.java
index 633c858d46..4d3ebf5bd7 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/ChildTemplate.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/ChildTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/ClusterTemplate.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/ClusterTemplate.java
index 44f3f7a51b..fcba35fa7d 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/ClusterTemplate.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/ClusterTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaFilterProcessor.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaFilterProcessor.java
index d692743f90..702d8501b3 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaFilterProcessor.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaFilterProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
@@ -39,6 +39,7 @@
import org.springframework.data.elasticsearch.core.geo.GeoJson;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.query.Criteria;
+import org.springframework.data.elasticsearch.utils.geohash.Geohash;
import org.springframework.data.geo.Box;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
@@ -69,10 +70,17 @@ public static Optional createQuery(Criteria criteria) {
for (Criteria chainedCriteria : criteria.getCriteriaChain()) {
if (chainedCriteria.isOr()) {
- BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
- queriesForEntries(chainedCriteria).forEach(boolQueryBuilder::should);
- filterQueries.add(new Query(boolQueryBuilder.build()));
+ Collection extends Query> queriesForEntries = queriesForEntries(chainedCriteria);
+
+ if (!queriesForEntries.isEmpty()) {
+ BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
+ queriesForEntries.forEach(boolQueryBuilder::should);
+ filterQueries.add(new Query(boolQueryBuilder.build()));
+ }
} else if (chainedCriteria.isNegating()) {
+
+ Assert.notNull(criteria.getField(), "criteria must have a field");
+
Collection extends Query> negatingFilters = buildNegatingFilter(criteria.getField().getName(),
criteria.getFilterCriteriaEntries());
filterQueries.addAll(negatingFilters);
@@ -116,6 +124,7 @@ private static Collection extends Query> buildNegatingFilter(String fieldName,
private static Collection extends Query> queriesForEntries(Criteria criteria) {
Assert.notNull(criteria.getField(), "criteria must have a field");
+
String fieldName = criteria.getField().getName();
Assert.notNull(fieldName, "Unknown field");
@@ -177,7 +186,7 @@ private static ObjectBuilder withinQuery(String fieldName, Obj
.distance(dist) //
.distanceType(GeoDistanceType.Plane) //
.location(location -> {
- if (values[0]instanceof GeoPoint loc) {
+ if (values[0] instanceof GeoPoint loc) {
location.latlon(latlon -> latlon.lat(loc.getLat()).lon(loc.getLon()));
} else if (values[0] instanceof Point point) {
GeoPoint loc = GeoPoint.fromPoint(point);
@@ -245,7 +254,7 @@ private static void twoParameterBBox(GeoBoundingBoxQuery.Builder queryBuilder, O
Assert.isTrue(allElementsAreOfType(values, GeoPoint.class) || allElementsAreOfType(values, String.class),
" both elements of boundedBy filter must be type of GeoPoint or text(format lat,lon or geohash)");
- if (values[0]instanceof GeoPoint topLeft) {
+ if (values[0] instanceof GeoPoint topLeft) {
GeoPoint bottomRight = (GeoPoint) values[1];
queryBuilder.boundingBox(bb -> bb //
.tlbr(tlbr -> tlbr //
@@ -267,7 +276,10 @@ private static void twoParameterBBox(GeoBoundingBoxQuery.Builder queryBuilder, O
.tlbr(tlbr -> tlbr //
.topLeft(glb -> {
if (isGeoHash) {
- glb.geohash(gh -> gh.geohash(topLeft));
+ // although the builder in 8.13.2 supports geohash, the server throws an error, so we convert to a
+ // lat,lon string here
+ glb.text(Geohash.toLatLon(topLeft));
+ // glb.geohash(gh -> gh.geohash(topLeft));
} else {
glb.text(topLeft);
}
@@ -275,7 +287,8 @@ private static void twoParameterBBox(GeoBoundingBoxQuery.Builder queryBuilder, O
}) //
.bottomRight(glb -> {
if (isGeoHash) {
- glb.geohash(gh -> gh.geohash(bottomRight));
+ glb.text(Geohash.toLatLon(bottomRight));
+ // glb.geohash(gh -> gh.geohash(bottomRight));
} else {
glb.text(bottomRight);
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryException.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryException.java
index 2d43553d55..cb6cccf973 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryException.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java
index 080920959e..1c9c9ef53a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
@@ -16,22 +16,28 @@
package org.springframework.data.elasticsearch.client.elc;
import static org.springframework.data.elasticsearch.client.elc.Queries.*;
+import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
import static org.springframework.util.StringUtils.*;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.ChildScoreMode;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
+import co.elastic.clients.elasticsearch.core.search.InnerHits;
import co.elastic.clients.json.JsonData;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.Field;
-import org.springframework.lang.Nullable;
+import org.springframework.data.elasticsearch.core.query.HasChildQuery;
+import org.springframework.data.elasticsearch.core.query.HasParentQuery;
+import org.springframework.data.elasticsearch.core.query.InnerHitsQuery;
import org.springframework.util.Assert;
/**
@@ -42,7 +48,7 @@
* @author Ezequiel Antúnez Camacho
* @since 4.4
*/
-class CriteriaQueryProcessor {
+class CriteriaQueryProcessor extends AbstractQueryProcessor {
/**
* creates a query from the criteria
@@ -110,11 +116,18 @@ public static Query createQuery(Criteria criteria) {
}
}
+ var filterQuery = CriteriaFilterProcessor.createQuery(criteria);
if (shouldQueries.isEmpty() && mustNotQueries.isEmpty() && mustQueries.isEmpty()) {
- return null;
+
+ if (filterQuery.isEmpty()) {
+ return null;
+ }
+
+ // we need something to add the filter to
+ mustQueries.add(Query.of(qb -> qb.matchAll(m -> m)));
}
- Query query = new Query.Builder().bool(boolQueryBuilder -> {
+ return new Query.Builder().bool(boolQueryBuilder -> {
if (!shouldQueries.isEmpty()) {
boolQueryBuilder.should(shouldQueries);
@@ -128,10 +141,10 @@ public static Query createQuery(Criteria criteria) {
boolQueryBuilder.must(mustQueries);
}
+ filterQuery.ifPresent(boolQueryBuilder::filter);
+
return boolQueryBuilder;
}).build();
-
- return query;
}
@Nullable
@@ -233,51 +246,57 @@ private static Query.Builder queryFor(Criteria.CriteriaEntry entry, Field field,
queryBuilder.queryString(queryStringQuery(fieldName, '*' + searchText, true, boost));
break;
case EXPRESSION:
- queryBuilder.queryString(queryStringQuery(fieldName, value.toString(), boost));
+ queryBuilder.queryString(queryStringQuery(fieldName, Objects.requireNonNull(value).toString(), boost));
break;
case LESS:
- queryBuilder //
- .range(rb -> rb //
- .field(fieldName) //
- .lt(JsonData.of(value)) //
- .boost(boost)); //
+ queryBuilder
+ .range(rb -> rb
+ .untyped(ut -> ut
+ .field(fieldName)
+ .lt(JsonData.of(value))
+ .boost(boost)));
break;
case LESS_EQUAL:
- queryBuilder //
- .range(rb -> rb //
- .field(fieldName) //
- .lte(JsonData.of(value)) //
- .boost(boost)); //
+ queryBuilder
+ .range(rb -> rb
+ .untyped(ut -> ut
+ .field(fieldName)
+ .lte(JsonData.of(value))
+ .boost(boost)));
break;
case GREATER:
- queryBuilder //
- .range(rb -> rb //
- .field(fieldName) //
- .gt(JsonData.of(value)) //
- .boost(boost)); //
+ queryBuilder
+ .range(rb -> rb
+ .untyped(ut -> ut
+ .field(fieldName)
+ .gt(JsonData.of(value))
+ .boost(boost)));
break;
case GREATER_EQUAL:
- queryBuilder //
- .range(rb -> rb //
- .field(fieldName) //
- .gte(JsonData.of(value)) //
- .boost(boost)); //
+ queryBuilder
+ .range(rb -> rb
+ .untyped(ut -> ut
+ .field(fieldName)
+ .gte(JsonData.of(value))
+ .boost(boost)));
break;
case BETWEEN:
Object[] ranges = (Object[]) value;
- queryBuilder //
- .range(rb -> {
- rb.field(fieldName);
- if (ranges[0] != null) {
- rb.gte(JsonData.of(ranges[0]));
- }
-
- if (ranges[1] != null) {
- rb.lte(JsonData.of(ranges[1]));
- }
- rb.boost(boost); //
- return rb;
- }); //
+ Assert.notNull(value, "value for a between condition must not be null");
+ queryBuilder
+ .range(rb -> rb
+ .untyped(ut -> {
+ ut.field(fieldName);
+ if (ranges[0] != null) {
+ ut.gte(JsonData.of(ranges[0]));
+ }
+
+ if (ranges[1] != null) {
+ ut.lte(JsonData.of(ranges[1]));
+ }
+ ut.boost(boost); //
+ return ut;
+ }));
break;
case FUZZY:
@@ -288,10 +307,10 @@ private static Query.Builder queryFor(Criteria.CriteriaEntry entry, Field field,
.boost(boost)); //
break;
case MATCHES:
- queryBuilder.match(matchQuery(fieldName, value.toString(), Operator.Or, boost));
+ queryBuilder.match(matchQuery(fieldName, Objects.requireNonNull(value).toString(), Operator.Or, boost));
break;
case MATCHES_ALL:
- queryBuilder.match(matchQuery(fieldName, value.toString(), Operator.And, boost));
+ queryBuilder.match(matchQuery(fieldName, Objects.requireNonNull(value).toString(), Operator.And, boost));
break;
case IN:
@@ -340,9 +359,35 @@ private static Query.Builder queryFor(Criteria.CriteriaEntry entry, Field field,
queryBuilder //
.regexp(rb -> rb //
.field(fieldName) //
- .value(value.toString()) //
+ .value(Objects.requireNonNull(value).toString()) //
.boost(boost)); //
break;
+ case HAS_CHILD:
+ if (value instanceof HasChildQuery query) {
+ queryBuilder.hasChild(hcb -> hcb
+ .type(query.getType())
+ .query(getEsQuery(query.getQuery(), null))
+ .innerHits(getInnerHits(query.getInnerHitsQuery()))
+ .ignoreUnmapped(query.getIgnoreUnmapped())
+ .minChildren(query.getMinChildren())
+ .maxChildren(query.getMaxChildren())
+ .scoreMode(scoreMode(query.getScoreMode())));
+ } else {
+ throw new CriteriaQueryException("value for " + fieldName + " is not a has_child query");
+ }
+ break;
+ case HAS_PARENT:
+ if (value instanceof HasParentQuery query) {
+ queryBuilder.hasParent(hpb -> hpb
+ .parentType(query.getParentType())
+ .query(getEsQuery(query.getQuery(), null))
+ .innerHits(getInnerHits(query.getInnerHitsQuery()))
+ .ignoreUnmapped(query.getIgnoreUnmapped())
+ .score(query.getScore()));
+ } else {
+ throw new CriteriaQueryException("value for " + fieldName + " is not a has_parent query");
+ }
+ break;
default:
throw new CriteriaQueryException("Could not build query for " + entry);
}
@@ -365,7 +410,7 @@ private static String orQueryString(Iterable> iterable) {
if (item != null) {
- if (sb.length() > 0) {
+ if (!sb.isEmpty()) {
sb.append(' ');
}
sb.append('"');
@@ -397,4 +442,19 @@ public static String escape(String s) {
return sb.toString();
}
+ /**
+ * Convert a spring-data-elasticsearch {@literal inner_hits} to an Elasticsearch {@literal inner_hits} query.
+ *
+ * @param query spring-data-elasticsearch {@literal inner_hits}.
+ * @return an Elasticsearch {@literal inner_hits} query.
+ */
+ @Nullable
+ private static InnerHits getInnerHits(@Nullable InnerHitsQuery query) {
+ if (query == null) {
+ return null;
+ }
+
+ return InnerHits.of(iqb -> iqb.from(query.getFrom()).size(query.getSize()).name(query.getName()));
+ }
+
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/DocumentAdapters.java
index 1b2dfadbb5..53e8cefa7b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/client/elc/DocumentAdapters.java
+++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/DocumentAdapters.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 the original author or authors.
+ * Copyright 2021-2025 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.
@@ -24,16 +24,9 @@
import co.elastic.clients.elasticsearch.core.search.NestedIdentity;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.JsonpMapper;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.MultiGetItem;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.document.Explanation;
@@ -41,200 +34,208 @@
import org.springframework.data.elasticsearch.core.document.SearchDocument;
import org.springframework.data.elasticsearch.core.document.SearchDocumentAdapter;
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
/**
* Utility class to adapt different Elasticsearch responses to a
* {@link org.springframework.data.elasticsearch.core.document.Document}
*
* @author Peter-Josef Meisch
* @author Haibo Liu
+ * @author Mohamed El Harrougui
* @since 4.4
*/
final class DocumentAdapters {
- private static final Log LOGGER = LogFactory.getLog(DocumentAdapters.class);
-
- private DocumentAdapters() {}
-
- /**
- * Creates a {@link SearchDocument} from a {@link Hit} returned by the Elasticsearch client.
- *
- * @param hit the hit object
- * @param jsonpMapper to map JsonData objects
- * @return the created {@link SearchDocument}
- */
- public static SearchDocument from(Hit> hit, JsonpMapper jsonpMapper) {
-
- Assert.notNull(hit, "hit must not be null");
-
- Map> highlightFields = hit.highlight();
-
- Map innerHits = new LinkedHashMap<>();
- hit.innerHits().forEach((name, innerHitsResult) -> {
- // noinspection ReturnOfNull
- innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, null, null,
- searchDocument -> null, jsonpMapper));
- });
-
- NestedMetaData nestedMetaData = from(hit.nested());
-
- Explanation explanation = from(hit.explanation());
-
- List matchedQueries = hit.matchedQueries();
-
- Function