Compare commits

..

52 Commits
main ... 5.2.8

Author SHA1 Message Date
Jens Schauder
eead581ff0
Release version 5.2.8 (2023.1.8).
See #2931
2024-07-12 13:33:06 +02:00
Jens Schauder
aef71db320
Prepare 5.2.8 (2023.1.8).
See #2931
2024-07-12 13:32:46 +02:00
Mark Paluch
452c76fb12
Switch to Broadcom docker proxy.
Closes #2934
2024-06-20 11:21:14 +02:00
Mark Paluch
c9a47997b9
After release cleanups.
See #2912
2024-06-14 10:06:43 +02:00
Mark Paluch
4a42c673ce
Prepare next development iteration.
See #2912
2024-06-14 10:06:42 +02:00
Mark Paluch
4729b9cfdc
Release version 5.2.7 (2023.1.7).
See #2912
2024-06-14 10:04:22 +02:00
Mark Paluch
aa16c0c5ab
Prepare 5.2.7 (2023.1.7).
See #2912
2024-06-14 10:04:05 +02:00
Peter-Josef Meisch
5e507fa163
Fix max dim value for dense vector.
Closes #2911

(cherry picked from commit e997b39f68bc0967c06c27a43e52b83afdb0b522)
(cherry picked from commit ba9edf8ec85f05cf2f1bdc3ead6598b3df3d04db)
2024-05-18 18:27:59 +02:00
Mark Paluch
a355537d78
After release cleanups.
See #2895
2024-05-17 11:24:38 +02:00
Mark Paluch
4fbf9f8b5a
Prepare next development iteration.
See #2895
2024-05-17 11:24:37 +02:00
Mark Paluch
2cb27c26d7
Release version 5.2.6 (2023.1.6).
See #2895
2024-05-17 11:22:24 +02:00
Mark Paluch
c322797eab
Prepare 5.2.6 (2023.1.6).
See #2895
2024-05-17 11:22:00 +02:00
Peter-Josef Meisch
c81958f62d
Fix implementation of explicit refresh policy.
Original Pull Request #2908
Closes #2907

(cherry picked from commit 94a40a7a752b6cf797d3e75fffe128f77f1c8468)
2024-05-10 09:35:20 +02:00
Peter-Josef Meisch
ed18be6f1c
Fix parameter in Order constructor.
Closes #2897

(cherry picked from commit ad66510e9e660577a2b8dff9e458d507e4351a42)
2024-04-15 21:11:35 +02:00
Mark Paluch
b3a21fbb7c
After release cleanups.
See #2873
2024-04-12 10:17:29 +02:00
Mark Paluch
d874b9d000
Prepare next development iteration.
See #2873
2024-04-12 10:17:28 +02:00
Mark Paluch
36e6a4b328
Release version 5.2.5 (2023.1.5).
See #2873
2024-04-12 10:15:11 +02:00
Mark Paluch
3710e47abd
Prepare 5.2.5 (2023.1.5).
See #2873
2024-04-12 10:14:56 +02:00
Mark Paluch
c40abc267b
After release cleanups.
See #2850
2024-03-15 10:20:09 +01:00
Mark Paluch
b479184d83
Prepare next development iteration.
See #2850
2024-03-15 10:20:08 +01:00
Mark Paluch
f2370bc7df
Release version 5.2.4 (2023.1.4).
See #2850
2024-03-15 10:17:49 +01:00
Mark Paluch
5f045d104e
Prepare 5.2.4 (2023.1.4).
See #2850
2024-03-15 10:17:30 +01:00
Peter-Josef Meisch
b52e8d1431
Fix setting setting id in bulkrequest.
Original Pull Request #2862
Closes #2861

(cherry picked from commit debf04b4996d4bebf67aef36d3927ad55731903c)
2024-02-28 21:45:49 +01:00
Mark Paluch
e86bb771be
After release cleanups.
See #2825
2024-02-16 13:53:53 +01:00
Mark Paluch
c9fbc17109
Prepare next development iteration.
See #2825
2024-02-16 13:53:51 +01:00
Mark Paluch
397e155d5e
Release version 5.2.3 (2023.1.3).
See #2825
2024-02-16 13:50:30 +01:00
Mark Paluch
4e52594d12
Prepare 5.2.3 (2023.1.3).
See #2825
2024-02-16 13:50:02 +01:00
Peter-Josef Meisch
310f0ed567
Fix criteria filter in native query.
Original Pull Request #2846
Closes #2840

(cherry picked from commit e9ecebd9efbe852249e1b2afea4733bb6ea5daee)
2024-02-06 21:23:50 +01:00
Peter-Josef Meisch
dab0be04db
Fix store null values implementation.
Original Pull Request #2842

(cherry picked from commit 0a1e20579ecd767fa161c5dd5a3988c38fa62225)
2024-01-31 17:32:41 +01:00
Mark Paluch
e8f269d9ec
Refine Artifactory build name.
See #2772
2024-01-31 15:13:58 +01:00
Peter-Josef Meisch
1e9824ae2d
Upgrade to Elasticsearch 8.11.4.
Original Pull Request #2829
Closes #2827
2024-01-19 07:18:40 +01:00
Mark Paluch
c9b8b3f33d
After release cleanups.
See #2804
2024-01-12 10:54:33 +01:00
Mark Paluch
a806553169
Prepare next development iteration.
See #2804
2024-01-12 10:54:32 +01:00
Mark Paluch
27011d382b
Release version 5.2.2 (2023.1.2).
See #2804
2024-01-12 10:51:32 +01:00
Mark Paluch
489a2605b4
Prepare 5.2.2 (2023.1.2).
See #2804
2024-01-12 10:50:44 +01:00
Peter-Josef Meisch
953f840d7c
Upgrade to Elasticsearch 8.11.3.
Original Pull Request #2823
Closes #2821
2024-01-06 17:37:27 +01:00
Mark Paluch
d905a4b25f
Extend license header copyright years to 2024.
See #2818
2024-01-02 13:54:48 +01:00
Peter-Josef Meisch
e2e6b5005b
Make org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate.ClientCallback public.
Original Pull Request #2815
Closes #2814

(cherry picked from commit 260dadd4d648b87dda5d18cc90ae457cce497735)
2023-12-29 13:57:56 +01:00
Peter-Josef Meisch
0d4e8ad6eb
Upgrade to Elasticsearch 8.11.2.
Original Pull Request #2809
2023-12-24 14:31:20 +01:00
Mark Paluch
a9bacd23b0
After release cleanups.
See #2771
2023-12-15 14:15:21 +01:00
Mark Paluch
031f7c8c78
Prepare next development iteration.
See #2771
2023-12-15 14:15:19 +01:00
Mark Paluch
76187a4934
Release version 5.2.1 (2023.1.1).
See #2771
2023-12-15 14:11:53 +01:00
Mark Paluch
b693494e17
Prepare 5.2.1 (2023.1.1).
See #2771
2023-12-15 14:11:23 +01:00
Mark Paluch
b324935d22
Update CI properties.
See #2771
2023-12-14 08:49:56 +01:00
Mark Paluch
920f7c029f
Upgrade to Maven Wrapper 3.9.6.
See #2799
2023-12-14 08:34:15 +01:00
Peter-Josef Meisch
051777ee25
Removed junk characters from code.
(cherry picked from commit 415d5e0385fa00709fcc599b0087a77c80a79270)
2023-11-30 20:44:26 +01:00
Peter-Josef Meisch
0fb98eda39
Fix type of returned sort values.
Original Pull Request #2786
Closes #2777

(cherry picked from commit 3833975a1ad76ef9c90b1260b090ff1eb9af523c)
2023-11-30 20:44:25 +01:00
Mark Paluch
df76b43cb4
Introduce property for Jenkins user and Artifactory server details.
Closes #2781
2023-11-27 14:23:49 +01:00
Runbing
b681197d0f
Fixed the URL for the Spring Data Commons documentation.
I fixed broken links in the Spring Data Elasticsearch documentation for Spring Data Commons.

Closes #2776
2023-11-20 11:31:58 +01:00
Mark Paluch
8a1323c11a
Update CI trigger versions.
See #2737
2023-11-17 14:53:43 +01:00
Mark Paluch
033d71ccb6
After release cleanups.
See #2737
2023-11-17 14:33:56 +01:00
Mark Paluch
0ae2a52de8
Prepare next development iteration.
See #2737
2023-11-17 14:33:54 +01:00
690 changed files with 3827 additions and 13136 deletions

4
.gitignore vendored
View File

@ -30,7 +30,7 @@ target
build/
node_modules
node
package.json
package-lock.json
.mvn/.develocity
/src/test/resources/testcontainers-local.properties
.mvn/.gradle-enterprise

View File

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

View File

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

View File

@ -1,14 +0,0 @@
--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

View File

@ -1,3 +1,3 @@
#Thu Nov 07 09:47:28 CET 2024
#Thu Dec 14 08:34:15 CET 2023
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.9/apache-maven-3.9.9-bin.zip
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip

14
Jenkinsfile vendored
View File

@ -9,7 +9,7 @@ pipeline {
triggers {
pollSCM 'H/10 * * * *'
upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS)
upstream(upstreamProjects: "spring-data-commons/3.2.x", threshold: hudson.model.Result.SUCCESS)
}
options {
@ -33,6 +33,7 @@ pipeline {
environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
}
@ -64,6 +65,7 @@ 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 {
@ -94,22 +96,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.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
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 " +
"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.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch " +
"-Dmaven.test.skip=true clean deploy -U -B"
}
}

View File

@ -1,4 +1,6 @@
= 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 Data Elasticsearch"]
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-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Gradle Enterprise", link="https://ge.spring.io/scans?search.rootProjectNames=Spring Data Elasticsearch"]
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.
@ -62,7 +64,7 @@ public class MyService {
=== Using the RestClient
Please check the https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration[official documentation].
Please check the [official documentation](https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration).
=== Maven configuration
@ -124,7 +126,8 @@ Wed 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 or chat with the community on https://app.gitter.im/#/room/#spring-projects_spring-data:gitter.im[Gitter].
* 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].
* 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
@ -168,7 +171,7 @@ Building the documentation builds also the project without running tests.
$ ./mvnw clean install -Pantora
----
The generated documentation is available from `target/site/index.html`.
The generated documentation is available from `target/antora/site/index.html`.
== Examples

View File

@ -2,7 +2,12 @@
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 -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
./mvnw -s settings.xml clean -Dscan=false -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch

View File

@ -1,20 +1,24 @@
# Java versions
java.main.tag=24.0.1_9-jdk-noble
java.next.tag=24.0.1_9-jdk-noble
java.main.tag=17.0.9_9-jdk-focal
java.next.tag=21.0.1_12-jdk-jammy
# Docker container images - standard
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.6.0.version=6.0.23
docker.mongodb.7.0.version=7.0.20
docker.mongodb.8.0.version=8.0.9
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
# Supported versions of Redis
docker.redis.6.version=6.2.13
docker.redis.7.version=7.2.4
# Supported versions of Cassandra
docker.cassandra.3.version=3.11.16
# Docker environment settings
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home
@ -27,5 +31,6 @@ 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

View File

@ -3,8 +3,15 @@
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 -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
-P${PROFILE} clean dependency:list verify -Dsort -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch

View File

@ -1,10 +0,0 @@
{
"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"
}
}

84
pom.xml
View File

@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>5.2.8</version>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>3.2.8</version>
</parent>
<name>Spring Data Elasticsearch</name>
@ -18,16 +18,17 @@
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties>
<springdata.commons>4.0.0-SNAPSHOT</springdata.commons>
<springdata.commons>3.2.8</springdata.commons>
<!-- version of the ElasticsearchClient -->
<elasticsearch-java>9.0.1</elasticsearch-java>
<elasticsearch-java>8.11.4</elasticsearch-java>
<hoverfly>0.19.0</hoverfly>
<log4j>2.23.1</log4j>
<jsonassert>1.5.3</jsonassert>
<testcontainers>1.20.0</testcontainers>
<wiremock>3.9.1</wiremock>
<blockhound-junit>1.0.8.RELEASE</blockhound-junit>
<hoverfly>0.14.4</hoverfly>
<log4j>2.18.0</log4j>
<jsonassert>1.5.1</jsonassert>
<testcontainers>1.18.0</testcontainers>
<wiremock>2.35.1</wiremock>
<java-module-name>spring.data.elasticsearch</java-module-name>
@ -131,10 +132,9 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<artifactId>elasticsearch-rest-client</artifactId> <!-- is Apache 2-->
<version>${elasticsearch-java}</version>
<exclusions>
<exclusion>
@ -144,13 +144,6 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>${querydsl}</version>
<optional>true</optional>
</dependency>
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
@ -255,6 +248,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound-junit-platform</artifactId>
<version>${blockhound-junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
@ -263,8 +263,8 @@
</dependency>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>${wiremock}</version>
<scope>test</scope>
<exclusions>
@ -324,13 +324,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>${archunit}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -443,6 +436,25 @@
</build>
</profile>
<profile>
<id>jdk13+</id>
<!-- on jDK13+, Blockhound needs this JVM flag set -->
<activation>
<jdk>[13,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-XX:+AllowRedefinitionToAddDeleteMethods</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>antora-process-resources</id>
<build>
@ -460,7 +472,7 @@
<build>
<plugins>
<plugin>
<groupId>org.antora</groupId>
<groupId>io.spring.maven.antora</groupId>
<artifactId>antora-maven-plugin</artifactId>
</plugin>
</plugins>
@ -469,20 +481,8 @@
</profiles>
<repositories>
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>

View File

@ -3,7 +3,8 @@
# The purpose of this Antora playbook is to build the docs in the current branch.
antora:
extensions:
- require: '@springio/antora-extensions'
- '@antora/collector-extension'
- require: '@springio/antora-extensions/root-component-extension'
root_component_name: 'data-elasticsearch'
site:
title: Spring Data Elasticsearch
@ -17,16 +18,17 @@ 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.4.x, 3.3.x ]
branches: [ main, 3.2.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: ''
@ -36,5 +38,5 @@ runtime:
format: pretty
ui:
bundle:
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip
snapshot: true

View File

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

View File

@ -9,10 +9,6 @@
*** 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[]
@ -43,5 +39,4 @@
** xref:repositories/query-keywords-reference.adoc[]
** xref:repositories/query-return-types-reference.adoc[]
* 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]
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki]

View File

@ -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.jspecify.annotations.Nullable;
import org.springframework.lang.Nullable;
public interface Persistable<ID> {
@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.

View File

@ -31,7 +31,7 @@ public class MyClientConfig extends ElasticsearchConfiguration {
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
====
The javadoc:org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration[]] class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
The `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 javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[]
<.> an implementation of `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 javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[] to interact with the Elasticsearch cluster.
Basically one should just use the `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 javadoc:org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchConfiguration[] class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
The `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 javadoc:org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations[]
<.> an implementation of `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 javadoc:org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations[] to interact with the Elasticsearch cluster.
Basically one should just use the `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 javadoc:org.springframework.data.elasticsearch.client.ClientConfiguration[] that allows to set options for SSL, connect and socket timeouts, headers and other parameters.
Client behaviour can be changed via the `ClientConfiguration` that allows to set options for SSL, connect and socket timeouts, headers and other parameters.
.Client Configuration
====
@ -150,7 +150,7 @@ ClientConfiguration clientConfiguration = ClientConfiguration.builder()
return headers;
})
.withClientConfigurer( <.>
ElasticsearchHttpClientConfigurationCallback.from(clientBuilder -> {
ElasticsearchClientConfigurationCallback.from(clientBuilder -> {
// ...
return clientBuilder;
}))
@ -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 javadoc:org.springframework.data.elasticsearch.client.ClientConfiguration[] class offers the most common parameters to configure the client.
The `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:
@ -192,7 +192,6 @@ This callback provides a `org.elasticsearch.client.RestClientBuilder` that can b
[source,java]
----
ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.withClientConfigurer(ElasticsearchClients.ElasticsearchRestClientConfigurationCallback.from(restClientBuilder -> {
// configure the Elasticsearch RestClient
return restClientBuilder;
@ -211,7 +210,6 @@ used by the `RestClient`.
[source,java]
----
ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.withClientConfigurer(ElasticsearchClients.ElasticsearchHttpClientConfigurationCallback.from(httpAsyncClientBuilder -> {
// configure the HttpAsyncClient
return httpAsyncClientBuilder;

View File

@ -1,39 +1,13 @@
[[new-features]]
= What's new
[[new-features.6-0-0]]
== New in Spring Data Elasticsearch 6.6
[[new-features.5-2-3]]
== New in Spring Data Elasticsearch 5.2.2
* Upgrade to Elasticsearch 8.11.4
* 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.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-2]]
== New in Spring Data Elasticsearch 5.2.2
* Upgrade to Elasticsearch 8.11.3
[[new-features.5-2-0]]
== New in Spring Data Elasticsearch 5.2

View File

@ -52,7 +52,7 @@ public class Statement {
return routing;
}
public void setRouting(String routing) {
public void setRouting(Routing 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,7 +226,6 @@ SearchHits<Statement> 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)

View File

@ -365,8 +365,6 @@ 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.
@ -451,3 +449,4 @@ 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.

View File

@ -192,7 +192,8 @@ 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!
@ -422,6 +423,7 @@ 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() //

View File

@ -12,10 +12,10 @@ class Book {
@Id
private String id;
@Field(type = FieldType.Text)
@Field(type = FieldType.text)
private String name;
@Field(type = FieldType.Text)
@Field(type = FieldType.text)
private String summary;
@Field(type = FieldType.Integer)

View File

@ -10,9 +10,7 @@ The Elasticsearch module supports all basic query building feature as string que
=== Declared queries
Deriving the query from the method name is not always sufficient and/or may result in unreadable method names.
In this case one might make 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] ).
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] ).
[[elasticsearch.query-methods.criterions]]
== Query creation
@ -314,13 +312,11 @@ Repository methods can be defined to have the following return types for returni
* `SearchPage<T>`
[[elasticsearch.query-methods.at-query]]
== Using the @Query Annotation
== Using @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<Book, String> {
@ -345,20 +341,15 @@ 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<SampleEntity> getByIds(Collection<String> 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]
----
{
@ -370,223 +361,3 @@ So calling the method with a `List` of `["id1", "id2", "id3"]` would produce the
}
----
====
[[elasticsearch.query-methods.at-query.spel]]
=== Using SpEL Expressions
.Declare query on the method using the `@Query` annotation with SpEL expression.
====
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<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"term":{
"name": "#{#name}"
}
}
]
}
}
""")
Page<Book> findByName(String name, Pageable pageable);
}
----
If for example the function is called with the parameter _John_, it would produce the following query body:
[source,json]
----
{
"bool":{
"must":[
{
"term":{
"name": "John"
}
}
]
}
}
----
====
.accessing parameter property.
====
Supposing that we have the following class as query parameter type:
[source,java]
----
public record QueryParameter(String value) {
}
----
It's easy to access the parameter by `#` symbol, then reference the property `value` with a simple `.`:
[source,java]
----
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"term":{
"name": "#{#parameter.value}"
}
}
]
}
}
""")
Page<Book> findByName(QueryParameter parameter, Pageable pageable);
}
----
We can pass `new QueryParameter("John")` as the parameter now, and it will produce the same query string as above.
====
.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:
[source,java]
----
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"term":{
"name": "#{@queryParameter.value}"
}
}
]
}
}
""")
Page<Book> findByName(Pageable pageable);
}
----
====
.SpEL and `Collection` param.
====
`Collection` parameter is also supported and is as easy to use as normal `String`, such as the following `terms` query:
[source,java]
----
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#names}
}
}
]
}
}
""")
Page<Book> findByName(Collection<String> names, Pageable pageable);
}
----
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]
----
{
"bool":{
"must":[
{
"terms":{
"name": ["name1", "name2"]
}
}
]
}
}
----
====
.access property in the `Collection` param.
====
https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/collection-projection.html[SpEL Collection Projection] is convenient to use when values in the `Collection` parameter is not plain `String`:
[source,java]
----
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#parameters.![value]}
}
}
]
}
}
""")
Page<Book> findByName(Collection<QueryParameter> 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.
====
.alter parameter name by using `@Param`
====
When accessing the parameter by SpEL, it's also useful to alter the parameter name to another one by `@Param` annotation in Sping Data:
[source,java]
----
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#another.![value]}
}
}
]
}
}
""")
Page<Book> findByName(@Param("another") Collection<QueryParameter> parameters, Pageable pageable);
}
----
====
[[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<Book, String> {
@SearchTemplateQuery(id = "book-by-title")
SearchHits<Book> 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.

View File

@ -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['birthDate'].value.toInstant();
Instant startDate = doc['birth-date'].value.toInstant();
emit (ChronoUnit.DAYS.between(startDate, currentDate) / 365);
""");

View File

@ -3,10 +3,10 @@
Spring Data Elasticsearch uses several interfaces to define the operations that can be called against an Elasticsearch index (for a description of the reactive interfaces see xref:elasticsearch/reactive-template.adoc[]).
* 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.
* `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.
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 or the execution duration it took to complete the request.
These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations.
The following classes and interfaces are now available:
.SearchHit<T>

View File

@ -6,13 +6,9 @@ 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
| 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
| 2023.1 (Vaughan) | 5.2.x | 8.11.4 | 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
| 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

View File

@ -49,7 +49,7 @@ Also the reactive implementation that was provided up to now has been moved here
If you are using `ElasticsearchRestTemplate` directly and not the `ElasticsearchOperations` interface you'll need to adjust your imports as well.
When working with the `NativeSearchQuery` class, you'll need to switch to the `NativeQuery` class, which can take a
`Query` instance coming from the new Elasticsearch client libraries.
`Query` instance comign from the new Elasticsearch client libraries.
You'll find plenty of examples in the test code.
[[elasticsearch-migration-guide-4.4-5.0.breaking-changes-records]]

View File

@ -1,21 +0,0 @@
[[elasticsearch-migration-guide-5.2-5.3]]
= Upgrading from 5.2.x to 5.3.x
This section describes breaking changes from version 5.2.x to 5.3.x and how removed features can be replaced by new introduced features.
[[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.

View File

@ -1,23 +0,0 @@
[[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

View File

@ -1,30 +0,0 @@
[[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)
```

View File

@ -1,21 +0,0 @@
[[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<UnfreezeRequest.Builder, ObjectBuilder<UnfreezeRequest>>)
```

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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,9 @@
*/
package org.springframework.data.elasticsearch;
import java.util.List;
import org.springframework.lang.Nullable;
import org.jspecify.annotations.Nullable;
import java.util.List;
/**
* Object describing an Elasticsearch error
@ -26,7 +26,8 @@ import org.jspecify.annotations.Nullable;
* @since 4.4
*/
public class ElasticsearchErrorCause {
@Nullable private final String type;
@Nullable
private final String type;
private final String reason;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2025 the original author or authors.
* Copyright 2019-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023-2025 the original author or authors.
* Copyright 2023-2024 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.

View File

@ -1,79 +0,0 @@
/*
* 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;
}

View File

@ -1,36 +0,0 @@
/*
* 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();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2025 the original author or authors.
* Copyright 2019-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 the original author or authors.
* Copyright 2013-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 the original author or authors.
* Copyright 2014-2024 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,173 +39,41 @@ public enum DateFormat {
basic_t_time("'T'HHmmss.SSSXXX"), //
basic_t_time_no_millis("'T'HHmmssXXX"), //
basic_week_date("YYYY'W'wwe"), // week-based-year!
/**
* @since 5.3
*/
strict_basic_week_date("YYYY'W'wwe"), // week-based-year!
basic_week_date_time("YYYY'W'wwe'T'HHmmss.SSSX"), // here Elasticsearch uses a different zone format
/**
* @since 5.3
*/
strict_basic_week_date_time("YYYY'W'wwe'T'HHmmss.SSSX"), // here Elasticsearch uses a different zone format
basic_week_date_time_no_millis("YYYY'W'wwe'T'HHmmssX"), //
/**
* @since 5.3
*/
strict_basic_week_date_time_no_millis("YYYY'W'wwe'T'HHmmssX"), //
date("uuuu-MM-dd"), //
/**
* @since 5.3
*/
strict_date("uuuu-MM-dd"), //
date_hour("uuuu-MM-dd'T'HH"), //
/**
* @since 5.3
*/
strict_date_hour("uuuu-MM-dd'T'HH"), //
date_hour_minute("uuuu-MM-dd'T'HH:mm"), //
/**
* @since 5.3
*/
strict_date_hour_minute("uuuu-MM-dd'T'HH:mm"), //
date_hour_minute_second("uuuu-MM-dd'T'HH:mm:ss"), //
/**
* @since 5.3
*/
strict_date_hour_minute_second("uuuu-MM-dd'T'HH:mm:ss"), //
date_hour_minute_second_fraction("uuuu-MM-dd'T'HH:mm:ss.SSS"), //
/**
* @since 5.3
*/
strict_date_hour_minute_second_fraction("uuuu-MM-dd'T'HH:mm:ss.SSS"), //
date_hour_minute_second_millis("uuuu-MM-dd'T'HH:mm:ss.SSS"), //
/**
* @since 5.3
*/
strict_date_hour_minute_second_millis("uuuu-MM-dd'T'HH:mm:ss.SSS"), //
date_optional_time("uuuu-MM-dd['T'HH:mm:ss.SSSXXX]"), //
/**
* @since 5.3
*/
strict_date_optional_time("uuuu-MM-dd['T'HH:mm:ss.SSSXXX]"), //
strict_date_optional_time_nanos("uuuu-MM-dd['T'HH:mm:ss.SSSSSSXXX]"), //
date_time("uuuu-MM-dd'T'HH:mm:ss.SSSXXX"), //
/**
* @since 5.3
*/
strict_date_time("uuuu-MM-dd'T'HH:mm:ss.SSSXXX"), //
date_time_no_millis("uuuu-MM-dd'T'HH:mm:ssVV"), // here Elasticsearch uses the zone-id in its implementation
/**
* @since 5.3
*/
strict_date_time_no_millis("uuuu-MM-dd'T'HH:mm:ssVV"), // here Elasticsearch uses the zone-id in its implementation
epoch_millis("epoch_millis"), //
epoch_second("epoch_second"), //
hour("HH"), //
/**
* @since 5.3
*/
strict_hour("HH"), //
hour_minute("HH:mm"), //
/**
* @since 5.3
*/
strict_hour_minute("HH:mm"), //
hour_minute_second("HH:mm:ss"), //
/**
* @since 5.3
*/
strict_hour_minute_second("HH:mm:ss"), //
hour_minute_second_fraction("HH:mm:ss.SSS"), //
/**
* @since 5.3
*/
strict_hour_minute_second_fraction("HH:mm:ss.SSS"), //
hour_minute_second_millis("HH:mm:ss.SSS"), //
/**
* @since 5.3
*/
strict_hour_minute_second_millis("HH:mm:ss.SSS"), //
ordinal_date("uuuu-DDD"), //
/**
* @since 5.3
*/
strict_ordinal_date("uuuu-DDD"), //
ordinal_date_time("uuuu-DDD'T'HH:mm:ss.SSSXXX"), //
/**
* @since 5.3
*/
strict_ordinal_date_time("uuuu-DDD'T'HH:mm:ss.SSSXXX"), //
ordinal_date_time_no_millis("uuuu-DDD'T'HH:mm:ssXXX"), //
/**
* @since 5.3
*/
strict_ordinal_date_time_no_millis("uuuu-DDD'T'HH:mm:ssXXX"), //
time("HH:mm:ss.SSSXXX"), //
/**
* @since 5.3
*/
strict_time("HH:mm:ss.SSSXXX"), //
time_no_millis("HH:mm:ssXXX"), //
/**
* @since 5.3
*/
strict_time_no_millis("HH:mm:ssXXX"), //
t_time("'T'HH:mm:ss.SSSXXX"), //
/**
* @since 5.3
*/
strict_t_time("'T'HH:mm:ss.SSSXXX"), //
t_time_no_millis("'T'HH:mm:ssXXX"), //
/**
* @since 5.3
*/
strict_t_time_no_millis("'T'HH:mm:ssXXX"), //
week_date("YYYY-'W'ww-e"), //
/**
* @since 5.3
*/
strict_week_date("YYYY-'W'ww-e"), //
week_date_time("YYYY-'W'ww-e'T'HH:mm:ss.SSSXXX"), //
/**
* @since 5.3
*/
strict_week_date_time("YYYY-'W'ww-e'T'HH:mm:ss.SSSXXX"), //
week_date_time_no_millis("YYYY-'W'ww-e'T'HH:mm:ssXXX"), //
/**
* @since 5.3
*/
strict_week_date_time_no_millis("YYYY-'W'ww-e'T'HH:mm:ssXXX"), //
weekyear(""), // no TemporalAccessor available for these 3
/**
* @since 5.3
*/
strict_weekyear(""), // no TemporalAccessor available for these 3
weekyear_week(""), //
/**
* @since 5.3
*/
strict_weekyear_week(""), //
weekyear_week_day(""), //
/**
* @since 5.3
*/
strict_strict_weekyear_week_day(""), //
year("uuuu"), //
/**
* @since 5.3
*/
strict_year("uuuu"), //
year_month("uuuu-MM"), //
/**
* @since 5.3
*/
strict_year_month("uuuu-MM"), //
year_month_day("uuuu-MM-dd"), //
/**
* @since 5.3
*/
strict_year_month_day("uuuu-MM-dd"); //
year_month_day("uuuu-MM-dd"); //
private final String pattern;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 the original author or authors.
* Copyright 2013-2024 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,13 +100,6 @@ public @interface Document {
*/
boolean storeVersionInSource() default true;
/**
* Aliases for the index.
*
* @since 5.4
*/
Alias[] aliases() default {};
/**
* @since 4.3
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 the original author or authors.
* Copyright 2013-2024 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,8 +37,6 @@ import org.springframework.core.annotation.AliasFor;
* @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 })
@ -130,10 +128,6 @@ public @interface Field {
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 "";
@ -201,27 +195,6 @@ public @interface Field {
*/
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.<br>
* To be used in combination with {@link FieldType#Object} or {@link FieldType#Nested}
@ -245,11 +218,4 @@ public @interface Field {
* @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 "";
}

View File

@ -1,26 +0,0 @@
/*
* 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";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 the original author or authors.
* Copyright 2013-2024 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.

View File

@ -1,38 +0,0 @@
/*
* 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 "";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 the original author or authors.
* Copyright 2013-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017-2025 the original author or authors.
* Copyright 2017-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.
@ -21,7 +21,6 @@ import java.lang.annotation.RetentionPolicy;
/**
* @author Peter-Josef Meisch
* @author Haibo Liu
* @since 4.0
*/
@Documented
@ -60,8 +59,6 @@ public @interface HighlightParameters {
int numberOfFragments() default -1;
Query highlightQuery() default @Query;
String order() default "";
int phraseLimit() default -1;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2025 the original author or authors.
* Copyright 2019-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2025 the original author or authors.
* Copyright 2019-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023-2025 the original author or authors.
* Copyright 2023-2024 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,6 +15,9 @@
*/
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;
@ -22,10 +25,10 @@ import java.lang.annotation.RetentionPolicy;
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.
* <p>
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 the original author or authors.
* Copyright 2014-2024 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,8 +29,6 @@ import java.lang.annotation.Target;
* @author Aleksei Arsenev
* @author Brian Kimmig
* @author Morgan Lutz
* @author Haibo Liu
* @author Andriy Redko
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
@ -151,32 +149,4 @@ public @interface InnerField {
* @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 "";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.

View File

@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@ -1,40 +0,0 @@
/*
* 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;
}

View File

@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 the original author or authors.
* Copyright 2014-2024 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.
@ -74,14 +74,7 @@ public @interface Mapping {
*/
String runtimeFieldsPath() default "";
/**
* field alias definitions to be written to the index mapping
*
* @since 5.3
*/
MappingAlias[] aliases() default {};
enum Detection {
DEFAULT, TRUE, FALSE
DEFAULT, TRUE, FALSE;
}
}

View File

@ -1,45 +0,0 @@
/*
* 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.Documented;
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;
/**
* Defines a field alias in the index mapping.
*
* @author Peter-Josef Meisch
* @since 5.3
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface MappingAlias {
/**
* the name of the alias.
*/
String name();
/**
* the path of the alias.
*/
String path();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 the original author or authors.
* Copyright 2014-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 the original author or authors.
* Copyright 2020-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 the original author or authors.
* Copyright 2013-2024 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.

View File

@ -1,42 +0,0 @@
/*
* 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();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014-2025 the original author or authors.
* Copyright 2014-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2025 the original author or authors.
* Copyright 2019-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2025 the original author or authors.
* Copyright 2019-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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 @@ public @interface ValueConverter {
* 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();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,2 +1,3 @@
@org.jspecify.annotations.NullMarked
@org.springframework.lang.NonNullApi
@org.springframework.lang.NonNullFields
package org.springframework.data.elasticsearch.annotations;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023-2025 the original author or authors.
* Copyright 2023-2024 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 org.springframework.data.util.ReactiveWrappers;
*/
public class ElasticsearchAotPredicates {
public static final Predicate<ReactiveWrappers.ReactiveLibrary> IS_REACTIVE_LIBRARY_AVAILABLE = (
public static final Predicate<ReactiveWrappers.ReactiveLibrary> IS_REACTIVE_LIBARARY_AVAILABLE = (
lib) -> ReactiveWrappers.isAvailable(lib);
public static boolean isReactorPresent() {
return IS_REACTIVE_LIBRARY_AVAILABLE.test(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR);
return IS_REACTIVE_LIBARARY_AVAILABLE.test(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023-2025 the original author or authors.
* Copyright 2023-2024 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,7 +19,6 @@ import static org.springframework.data.elasticsearch.aot.ElasticsearchAotPredica
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;
@ -33,6 +32,7 @@ import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCal
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

View File

@ -1,2 +1,3 @@
@org.jspecify.annotations.NullMarked
@org.springframework.lang.NonNullApi
@org.springframework.lang.NonNullFields
package org.springframework.data.elasticsearch.aot;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018-2025 the original author or authors.
* Copyright 2018-2024 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 java.util.function.Supplier;
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.
@ -233,15 +233,6 @@ public interface ClientConfiguration {
*/
TerminalClientConfigurationBuilder usingSsl();
/**
* Connects using https if flag is true.
*
* @param flag whether to use https in the connection
* @return the {@link TerminalClientConfigurationBuilder}
* @since 5.3
*/
TerminalClientConfigurationBuilder usingSsl(boolean flag);
/**
* Connect via {@literal https} using the given {@link SSLContext}.<br />
* <strong>NOTE</strong> You need to leave out the protocol in

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018-2025 the original author or authors.
* Copyright 2018-2024 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,12 @@ import java.util.function.Supplier;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.jspecify.annotations.Nullable;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
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;
/**
@ -105,13 +106,6 @@ class ClientConfigurationBuilder
return this;
}
@Override
public TerminalClientConfigurationBuilder usingSsl(boolean flag) {
this.useSsl = flag;
return this;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder#usingSsl(javax.net.ssl.SSLContext)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018-2025 the original author or authors.
* Copyright 2018-2024 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,8 +24,9 @@ import java.util.function.Supplier;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.jspecify.annotations.Nullable;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.springframework.data.elasticsearch.support.HttpHeaders;
import org.springframework.lang.Nullable;
/**
* Default {@link ClientConfiguration} implementation.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018-2025 the original author or authors.
* Copyright 2018-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018-2025 the original author or authors.
* Copyright 2018-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018-2025 the original author or authors.
* Copyright 2018-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

View File

@ -1,70 +0,0 @@
/*
* 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<Query> 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;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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,10 +16,9 @@
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;
@ -38,10 +37,12 @@ public class AutoCloseableElasticsearchClient extends ElasticsearchClient implem
}
@Override
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();
public void close() throws Exception {
transport.close();
}
@Override
public ElasticsearchClusterClient cluster() {
return super.cluster();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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,7 +39,6 @@ import org.springframework.data.elasticsearch.core.geo.GeoBox;
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;
@ -51,7 +50,6 @@ import org.springframework.util.Assert;
* filter.
*
* @author Peter-Josef Meisch
* @author Junghoon Ban
* @since 4.4
*/
class CriteriaFilterProcessor {
@ -70,17 +68,10 @@ class CriteriaFilterProcessor {
for (Criteria chainedCriteria : criteria.getCriteriaChain()) {
if (chainedCriteria.isOr()) {
Collection<? extends Query> queriesForEntries = queriesForEntries(chainedCriteria);
if (!queriesForEntries.isEmpty()) {
BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
queriesForEntries.forEach(boolQueryBuilder::should);
filterQueries.add(new Query(boolQueryBuilder.build()));
}
BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
queriesForEntries(chainedCriteria).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);
@ -124,7 +115,6 @@ class CriteriaFilterProcessor {
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");
@ -179,17 +169,17 @@ class CriteriaFilterProcessor {
Assert.isTrue(values[1] instanceof String || values[1] instanceof Distance,
"Second element of a geo distance filter must be a text or a Distance");
String dist = (values[1] instanceof Distance distance) ? extractDistanceString(distance) : (String) values[1];
String dist = (values[1] instanceof Distance) ? extractDistanceString((Distance) values[1]) : (String) values[1];
return QueryBuilders.geoDistance() //
.field(fieldName) //
.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);
} else if (values[0] instanceof Point) {
GeoPoint loc = GeoPoint.fromPoint((Point) values[0]);
location.latlon(latlon -> latlon.lat(loc.getLat()).lon(loc.getLon()));
} else {
String loc = (String) values[0];
@ -230,8 +220,8 @@ class CriteriaFilterProcessor {
"single-element of boundedBy filter must be type of GeoBox or Box");
GeoBox geoBBox;
if (value instanceof Box box) {
geoBBox = GeoBox.fromBox(box);
if (value instanceof Box) {
geoBBox = GeoBox.fromBox((Box) value);
} else {
geoBBox = (GeoBox) value;
}
@ -254,7 +244,7 @@ class CriteriaFilterProcessor {
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 //
@ -276,10 +266,7 @@ class CriteriaFilterProcessor {
.tlbr(tlbr -> tlbr //
.topLeft(glb -> {
if (isGeoHash) {
// 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));
glb.geohash(gh -> gh.geohash(topLeft));
} else {
glb.text(topLeft);
}
@ -287,8 +274,7 @@ class CriteriaFilterProcessor {
}) //
.bottomRight(glb -> {
if (isGeoHash) {
glb.text(Geohash.toLatLon(bottomRight));
// glb.geohash(gh -> gh.geohash(bottomRight));
glb.geohash(gh -> gh.geohash(bottomRight));
} else {
glb.text(bottomRight);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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,28 +16,22 @@
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.data.elasticsearch.core.query.HasChildQuery;
import org.springframework.data.elasticsearch.core.query.HasParentQuery;
import org.springframework.data.elasticsearch.core.query.InnerHitsQuery;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@ -48,7 +42,7 @@ import org.springframework.util.Assert;
* @author Ezequiel Antúnez Camacho
* @since 4.4
*/
class CriteriaQueryProcessor extends AbstractQueryProcessor {
class CriteriaQueryProcessor {
/**
* creates a query from the criteria
@ -116,18 +110,11 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
}
}
var filterQuery = CriteriaFilterProcessor.createQuery(criteria);
if (shouldQueries.isEmpty() && mustNotQueries.isEmpty() && mustQueries.isEmpty()) {
if (filterQuery.isEmpty()) {
return null;
}
// we need something to add the filter to
mustQueries.add(Query.of(qb -> qb.matchAll(m -> m)));
return null;
}
return new Query.Builder().bool(boolQueryBuilder -> {
Query query = new Query.Builder().bool(boolQueryBuilder -> {
if (!shouldQueries.isEmpty()) {
boolQueryBuilder.should(shouldQueries);
@ -141,10 +128,10 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
boolQueryBuilder.must(mustQueries);
}
filterQuery.ifPresent(boolQueryBuilder::filter);
return boolQueryBuilder;
}).build();
return query;
}
@Nullable
@ -187,12 +174,6 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
.scoreMode(ChildScoreMode.Avg));
}
if (criteria.isNegating() && criteria.isOr()) {
final Query query = queryBuilder.build();
queryBuilder = new Query.Builder();
queryBuilder.bool(mnqb -> mnqb.mustNot(query));
}
return queryBuilder.build();
}
@ -246,57 +227,51 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
queryBuilder.queryString(queryStringQuery(fieldName, '*' + searchText, true, boost));
break;
case EXPRESSION:
queryBuilder.queryString(queryStringQuery(fieldName, Objects.requireNonNull(value).toString(), boost));
queryBuilder.queryString(queryStringQuery(fieldName, value.toString(), boost));
break;
case LESS:
queryBuilder
.range(rb -> rb
.untyped(ut -> ut
.field(fieldName)
.lt(JsonData.of(value))
.boost(boost)));
queryBuilder //
.range(rb -> rb //
.field(fieldName) //
.lt(JsonData.of(value)) //
.boost(boost)); //
break;
case LESS_EQUAL:
queryBuilder
.range(rb -> rb
.untyped(ut -> ut
.field(fieldName)
.lte(JsonData.of(value))
.boost(boost)));
queryBuilder //
.range(rb -> rb //
.field(fieldName) //
.lte(JsonData.of(value)) //
.boost(boost)); //
break;
case GREATER:
queryBuilder
.range(rb -> rb
.untyped(ut -> ut
.field(fieldName)
.gt(JsonData.of(value))
.boost(boost)));
queryBuilder //
.range(rb -> rb //
.field(fieldName) //
.gt(JsonData.of(value)) //
.boost(boost)); //
break;
case GREATER_EQUAL:
queryBuilder
.range(rb -> rb
.untyped(ut -> ut
.field(fieldName)
.gte(JsonData.of(value))
.boost(boost)));
queryBuilder //
.range(rb -> rb //
.field(fieldName) //
.gte(JsonData.of(value)) //
.boost(boost)); //
break;
case BETWEEN:
Object[] ranges = (Object[]) value;
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]));
}
queryBuilder //
.range(rb -> {
rb.field(fieldName);
if (ranges[0] != null) {
rb.gte(JsonData.of(ranges[0]));
}
if (ranges[1] != null) {
ut.lte(JsonData.of(ranges[1]));
}
ut.boost(boost); //
return ut;
}));
if (ranges[1] != null) {
rb.lte(JsonData.of(ranges[1]));
}
rb.boost(boost); //
return rb;
}); //
break;
case FUZZY:
@ -307,10 +282,10 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
.boost(boost)); //
break;
case MATCHES:
queryBuilder.match(matchQuery(fieldName, Objects.requireNonNull(value).toString(), Operator.Or, boost));
queryBuilder.match(matchQuery(fieldName, value.toString(), Operator.Or, boost));
break;
case MATCHES_ALL:
queryBuilder.match(matchQuery(fieldName, Objects.requireNonNull(value).toString(), Operator.And, boost));
queryBuilder.match(matchQuery(fieldName, value.toString(), Operator.And, boost));
break;
case IN:
@ -359,35 +334,9 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
queryBuilder //
.regexp(rb -> rb //
.field(fieldName) //
.value(Objects.requireNonNull(value).toString()) //
.value(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);
}
@ -410,7 +359,7 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
if (item != null) {
if (!sb.isEmpty()) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append('"');
@ -442,19 +391,4 @@ class CriteriaQueryProcessor extends AbstractQueryProcessor {
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()));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2025 the original author or authors.
* Copyright 2021-2024 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,17 +24,6 @@ import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.NestedIdentity;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.JsonpMapper;
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;
import org.springframework.data.elasticsearch.core.document.NestedMetaData;
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.util.Assert;
import java.util.Collections;
import java.util.LinkedHashMap;
@ -43,199 +32,208 @@ 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.springframework.data.elasticsearch.core.MultiGetItem;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.document.Explanation;
import org.springframework.data.elasticsearch.core.document.NestedMetaData;
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;
/**
* 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 static final Log LOGGER = LogFactory.getLog(DocumentAdapters.class);
private DocumentAdapters() {
}
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) {
/**
* 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");
Assert.notNull(hit, "hit must not be null");
Map<String, List<String>> highlightFields = hit.highlight();
Map<String, List<String>> highlightFields = hit.highlight();
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
hit.innerHits().forEach((name, innerHitsResult) -> {
// noinspection ReturnOfNull
innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, 0, null, null,
searchDocument -> null, jsonpMapper));
});
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
hit.innerHits().forEach((name, innerHitsResult) -> {
// noinspection ReturnOfNull
innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, null,
searchDocument -> null, jsonpMapper));
});
NestedMetaData nestedMetaData = from(hit.nested());
NestedMetaData nestedMetaData = from(hit.nested());
Explanation explanation = from(hit.explanation());
Explanation explanation = from(hit.explanation());
Map<String, Double> matchedQueries = hit.matchedQueries();
List<String> matchedQueries = hit.matchedQueries();
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
StringBuilder sb = new StringBuilder("{");
final boolean[] firstField = {true};
hit.fields().forEach((key, jsonData) -> {
if (!firstField[0]) {
sb.append(',');
}
sb.append('"').append(key).append("\":") //
.append(jsonData.toJson(jsonpMapper).toString());
firstField[0] = false;
});
sb.append('}');
return new EntityAsMap().fromJson(sb.toString());
};
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
StringBuilder sb = new StringBuilder("{");
final boolean[] firstField = { true };
hit.fields().forEach((key, jsonData) -> {
if (!firstField[0]) {
sb.append(',');
}
sb.append('"').append(key).append("\":") //
.append(jsonData.toJson(jsonpMapper).toString());
firstField[0] = false;
});
sb.append('}');
return new EntityAsMap().fromJson(sb.toString());
};
EntityAsMap hitFieldsAsMap = fromFields.apply(hit.fields());
EntityAsMap hitFieldsAsMap = fromFields.apply(hit.fields());
Map<String, List<Object>> documentFields = new LinkedHashMap<>();
hitFieldsAsMap.forEach((key, value) -> {
if (value instanceof List) {
// noinspection unchecked
documentFields.put(key, (List<Object>) value);
} else {
documentFields.put(key, Collections.singletonList(value));
}
});
Map<String, List<Object>> documentFields = new LinkedHashMap<>();
hitFieldsAsMap.forEach((key, value) -> {
if (value instanceof List) {
// noinspection unchecked
documentFields.put(key, (List<Object>) value);
} else {
documentFields.put(key, Collections.singletonList(value));
}
});
Document document;
Object source = hit.source();
if (source == null) {
document = Document.from(hitFieldsAsMap);
} else {
if (source instanceof EntityAsMap entityAsMap) {
document = Document.from(entityAsMap);
} else if (source instanceof JsonData jsonData) {
document = Document.from(jsonData.to(EntityAsMap.class));
} else {
Document document;
Object source = hit.source();
if (source == null) {
document = Document.from(hitFieldsAsMap);
} else {
if (source instanceof EntityAsMap entityAsMap) {
document = Document.from(entityAsMap);
} else if (source instanceof JsonData jsonData) {
document = Document.from(jsonData.to(EntityAsMap.class));
} else {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(String.format("Cannot map from type " + source.getClass().getName()));
}
document = Document.create();
}
}
document.setIndex(hit.index());
document.setId(hit.id());
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(String.format("Cannot map from type " + source.getClass().getName()));
}
document = Document.create();
}
}
document.setIndex(hit.index());
document.setId(hit.id());
if (hit.version() != null) {
document.setVersion(hit.version());
}
document.setSeqNo(hit.seqNo() != null && hit.seqNo() >= 0 ? hit.seqNo() : -2); // -2 was the default value in the
// old client
document.setPrimaryTerm(hit.primaryTerm() != null && hit.primaryTerm() > 0 ? hit.primaryTerm() : 0);
if (hit.version() != null) {
document.setVersion(hit.version());
}
document.setSeqNo(hit.seqNo() != null && hit.seqNo() >= 0 ? hit.seqNo() : -2); // -2 was the default value in the
// old client
document.setPrimaryTerm(hit.primaryTerm() != null && hit.primaryTerm() > 0 ? hit.primaryTerm() : 0);
float score = hit.score() != null ? hit.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, hit.sort().stream().map(TypeUtils::toObject).toArray(),
documentFields, highlightFields, innerHits, nestedMetaData, explanation, matchedQueries, hit.routing());
}
float score = hit.score() != null ? hit.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, hit.sort().stream().map(TypeUtils::toObject).toArray(),
documentFields, highlightFields, innerHits, nestedMetaData, explanation, matchedQueries, hit.routing());
}
public static SearchDocument from(CompletionSuggestOption<EntityAsMap> completionSuggestOption) {
public static SearchDocument from(CompletionSuggestOption<EntityAsMap> completionSuggestOption) {
Document document = completionSuggestOption.source() != null ? Document.from(completionSuggestOption.source())
: Document.create();
document.setIndex(completionSuggestOption.index());
Document document = completionSuggestOption.source() != null ? Document.from(completionSuggestOption.source())
: Document.create();
document.setIndex(completionSuggestOption.index());
if (completionSuggestOption.id() != null) {
document.setId(completionSuggestOption.id());
}
if (completionSuggestOption.id() != null) {
document.setId(completionSuggestOption.id());
}
float score = completionSuggestOption.score() != null ? completionSuggestOption.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, new Object[]{}, Collections.emptyMap(), Collections.emptyMap(),
Collections.emptyMap(), null, null, null, completionSuggestOption.routing());
}
float score = completionSuggestOption.score() != null ? completionSuggestOption.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, new Object[] {}, Collections.emptyMap(), Collections.emptyMap(),
Collections.emptyMap(), null, null, null, completionSuggestOption.routing());
}
@Nullable
private static Explanation from(co.elastic.clients.elasticsearch.core.explain.@Nullable Explanation explanation) {
@Nullable
private static Explanation from(@Nullable co.elastic.clients.elasticsearch.core.explain.Explanation explanation) {
if (explanation == null) {
return null;
}
List<Explanation> details = explanation.details().stream().map(DocumentAdapters::from).collect(Collectors.toList());
return new Explanation(true, (double) explanation.value(), explanation.description(), details);
}
if (explanation == null) {
return null;
}
List<Explanation> details = explanation.details().stream().map(DocumentAdapters::from).collect(Collectors.toList());
return new Explanation(true, (double) explanation.value(), explanation.description(), details);
}
private static Explanation from(ExplanationDetail explanationDetail) {
private static Explanation from(ExplanationDetail explanationDetail) {
List<Explanation> details = explanationDetail.details().stream().map(DocumentAdapters::from)
.collect(Collectors.toList());
return new Explanation(null, (double) explanationDetail.value(), explanationDetail.description(), details);
}
List<Explanation> details = explanationDetail.details().stream().map(DocumentAdapters::from)
.collect(Collectors.toList());
return new Explanation(null, (double) explanationDetail.value(), explanationDetail.description(), details);
}
@Nullable
private static NestedMetaData from(@Nullable NestedIdentity nestedIdentity) {
@Nullable
private static NestedMetaData from(@Nullable NestedIdentity nestedIdentity) {
if (nestedIdentity == null) {
return null;
}
if (nestedIdentity == null) {
return null;
}
NestedMetaData child = from(nestedIdentity.nested());
return NestedMetaData.of(nestedIdentity.field(), nestedIdentity.offset(), child);
}
NestedMetaData child = from(nestedIdentity.nested());
return NestedMetaData.of(nestedIdentity.field(), nestedIdentity.offset(), child);
}
/**
* Creates a {@link Document} from a {@link GetResponse} where the found document is contained as {@link EntityAsMap}.
*
* @param getResponse the response instance
* @return the Document
*/
@Nullable
public static Document from(GetResult<EntityAsMap> getResponse) {
/**
* Creates a {@link Document} from a {@link GetResponse} where the found document is contained as {@link EntityAsMap}.
*
* @param getResponse the response instance
* @return the Document
*/
@Nullable
public static Document from(GetResult<EntityAsMap> getResponse) {
Assert.notNull(getResponse, "getResponse must not be null");
Assert.notNull(getResponse, "getResponse must not be null");
if (!getResponse.found()) {
return null;
}
if (!getResponse.found()) {
return null;
}
Document document = getResponse.source() != null ? Document.from(getResponse.source()) : Document.create();
document.setIndex(getResponse.index());
document.setId(getResponse.id());
Document document = getResponse.source() != null ? Document.from(getResponse.source()) : Document.create();
document.setIndex(getResponse.index());
document.setId(getResponse.id());
if (getResponse.version() != null) {
document.setVersion(getResponse.version());
}
if (getResponse.version() != null) {
document.setVersion(getResponse.version());
}
if (getResponse.seqNo() != null) {
document.setSeqNo(getResponse.seqNo());
}
if (getResponse.seqNo() != null) {
document.setSeqNo(getResponse.seqNo());
}
if (getResponse.primaryTerm() != null) {
document.setPrimaryTerm(getResponse.primaryTerm());
}
if (getResponse.primaryTerm() != null) {
document.setPrimaryTerm(getResponse.primaryTerm());
}
return document;
}
return document;
}
/**
* Creates a list of {@link MultiGetItem}s from a {@link MgetResponse} where the data is contained as
* {@link EntityAsMap} instances.
*
* @param mgetResponse the response instance
* @return list of multiget items
*/
public static List<MultiGetItem<Document>> from(MgetResponse<EntityAsMap> mgetResponse) {
/**
* Creates a list of {@link MultiGetItem}s from a {@link MgetResponse} where the data is contained as
* {@link EntityAsMap} instances.
*
* @param mgetResponse the response instance
* @return list of multiget items
*/
public static List<MultiGetItem<Document>> from(MgetResponse<EntityAsMap> mgetResponse) {
Assert.notNull(mgetResponse, "mgetResponse must not be null");
Assert.notNull(mgetResponse, "mgetResponse must not be null");
return mgetResponse.docs().stream() //
.map(itemResponse -> MultiGetItem.of( //
itemResponse.isFailure() ? null : from(itemResponse.result()), //
ResponseConverter.getFailure(itemResponse)))
.collect(Collectors.toList());
}
return mgetResponse.docs().stream() //
.map(itemResponse -> MultiGetItem.of( //
itemResponse.isFailure() ? null : from(itemResponse.result()), //
ResponseConverter.getFailure(itemResponse)))
.collect(Collectors.toList());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022-2025 the original author or authors.
* Copyright 2022-2024 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.

Some files were not shown because too many files have changed in this diff Show More