mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-13 05:43:26 +00:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1b50013fc2 | ||
|
5418ef9e03 | ||
|
8d81e499bc | ||
|
e457b1678b | ||
|
6c34dc53f3 | ||
|
85b6acebb2 | ||
|
00155c2b31 | ||
|
d0020be57d | ||
|
20a6140fe9 | ||
|
cdb48c8226 | ||
|
493476567a | ||
|
a7c148653f | ||
|
3092db9e7d | ||
|
d8917f1cb1 | ||
|
cc533b25f1 | ||
|
c5231d879d | ||
|
950ca0fc2a | ||
|
95a86f558b | ||
|
8117e5a174 | ||
|
3a9a959918 | ||
|
a179dd0643 | ||
|
310ea07c6f | ||
|
34a277cd7d | ||
|
878dc029ec | ||
|
c931812c6a | ||
|
c514e020b8 | ||
|
31a4ad715f | ||
|
03efe1b910 | ||
|
9d5d2efb40 | ||
|
b7266961d9 | ||
|
d96cd02572 | ||
|
ceb0225850 | ||
|
5c59f73e00 | ||
|
44b1c9e848 | ||
|
1770f98a74 | ||
|
bad0a80313 | ||
|
92dd6e8599 | ||
|
c793be8ab4 | ||
|
07ae79f9ce | ||
|
47c84b84af | ||
|
5ba1e5dc77 | ||
|
5ddcd55942 | ||
|
be4a77ad21 | ||
|
7fa3cb74a1 | ||
|
ba9edf8ec8 | ||
|
e4a39ae285 | ||
|
7392222793 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -30,7 +30,6 @@ target
|
|||||||
build/
|
build/
|
||||||
node_modules
|
node_modules
|
||||||
node
|
node
|
||||||
package.json
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
.mvn/.gradle-enterprise
|
.mvn/.develocity
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extensions>
|
<extensions>
|
||||||
<extension>
|
<extension>
|
||||||
<groupId>com.gradle</groupId>
|
<groupId>io.spring.develocity.conventions</groupId>
|
||||||
<artifactId>gradle-enterprise-maven-extension</artifactId>
|
<artifactId>develocity-conventions-maven-extension</artifactId>
|
||||||
<version>1.19.2</version>
|
<version>0.0.19</version>
|
||||||
</extension>
|
|
||||||
<extension>
|
|
||||||
<groupId>com.gradle</groupId>
|
|
||||||
<artifactId>common-custom-user-data-maven-extension</artifactId>
|
|
||||||
<version>1.12.4</version>
|
|
||||||
</extension>
|
</extension>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
|
||||||
<gradleEnterprise
|
|
||||||
xmlns="https://www.gradle.com/gradle-enterprise-maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="https://www.gradle.com/gradle-enterprise-maven https://www.gradle.com/schema/gradle-enterprise-maven.xsd">
|
|
||||||
<server>
|
|
||||||
<url>https://ge.spring.io</url>
|
|
||||||
</server>
|
|
||||||
<buildScan>
|
|
||||||
<backgroundBuildScanUpload>false</backgroundBuildScanUpload>
|
|
||||||
<captureGoalInputFiles>true</captureGoalInputFiles>
|
|
||||||
<publishIfAuthenticated>true</publishIfAuthenticated>
|
|
||||||
<obfuscation>
|
|
||||||
<ipAddresses>#{{'0.0.0.0'}}</ipAddresses>
|
|
||||||
</obfuscation>
|
|
||||||
</buildScan>
|
|
||||||
<buildCache>
|
|
||||||
<local>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
</local>
|
|
||||||
<remote>
|
|
||||||
<server>
|
|
||||||
<credentials>
|
|
||||||
<username>${env.GRADLE_ENTERPRISE_CACHE_USERNAME}</username>
|
|
||||||
<password>${env.GRADLE_ENTERPRISE_CACHE_PASSWORD}</password>
|
|
||||||
</credentials>
|
|
||||||
</server>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
<storeEnabled>#{env['GRADLE_ENTERPRISE_CACHE_USERNAME'] != null and env['GRADLE_ENTERPRISE_CACHE_PASSWORD'] != null}</storeEnabled>
|
|
||||||
</remote>
|
|
||||||
</buildCache>
|
|
||||||
</gradleEnterprise>
|
|
4
.mvn/wrapper/maven-wrapper.properties
vendored
4
.mvn/wrapper/maven-wrapper.properties
vendored
@ -1,3 +1,3 @@
|
|||||||
#Thu Dec 14 08:40:44 CET 2023
|
#Thu Nov 07 09:49:32 CET 2024
|
||||||
wrapperUrl=https\://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
wrapperUrl=https\://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
||||||
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
|
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||||
|
20
Jenkinsfile
vendored
20
Jenkinsfile
vendored
@ -9,7 +9,7 @@ pipeline {
|
|||||||
|
|
||||||
triggers {
|
triggers {
|
||||||
pollSCM 'H/10 * * * *'
|
pollSCM 'H/10 * * * *'
|
||||||
upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS)
|
upstream(upstreamProjects: "spring-data-commons/3.3.x", threshold: hudson.model.Result.SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
options {
|
options {
|
||||||
@ -33,12 +33,12 @@ pipeline {
|
|||||||
|
|
||||||
environment {
|
environment {
|
||||||
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
|
|
||||||
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
|
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
|
docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
|
||||||
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
|
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
|
||||||
sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh"
|
sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh"
|
||||||
sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
|
sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
|
||||||
@ -46,6 +46,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage("Test other configurations") {
|
stage("Test other configurations") {
|
||||||
when {
|
when {
|
||||||
@ -63,11 +64,11 @@ pipeline {
|
|||||||
options { timeout(time: 30, unit: 'MINUTES') }
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
environment {
|
environment {
|
||||||
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
|
|
||||||
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
|
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
|
docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
|
||||||
docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) {
|
docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) {
|
||||||
sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh"
|
sh "PROFILE=none JENKINS_USER_NAME=${p['jenkins.user.name']} ci/verify.sh"
|
||||||
sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
|
sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
|
||||||
@ -77,6 +78,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Release to artifactory') {
|
stage('Release to artifactory') {
|
||||||
when {
|
when {
|
||||||
@ -92,29 +94,29 @@ pipeline {
|
|||||||
options { timeout(time: 20, unit: 'MINUTES') }
|
options { timeout(time: 20, unit: 'MINUTES') }
|
||||||
environment {
|
environment {
|
||||||
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
DEVELOCITY_CACHE = credentials("${p['develocity.cache.credentials']}")
|
|
||||||
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
|
DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
|
docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
|
||||||
|
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
|
||||||
sh 'MAVEN_OPTS="-Duser.name=' + "${p['jenkins.user.name']}" + ' -Duser.home=/tmp/jenkins-home" ' +
|
sh 'MAVEN_OPTS="-Duser.name=' + "${p['jenkins.user.name']}" + ' -Duser.home=/tmp/jenkins-home" ' +
|
||||||
"DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR} " +
|
"./mvnw -s settings.xml -Pci,artifactory " +
|
||||||
"DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW} " +
|
"-Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root " +
|
||||||
"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.server=${p['artifactory.url']} " +
|
||||||
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||||
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
|
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
|
||||||
"-Dartifactory.staging-repository=${p['artifactory.repository.snapshot']} " +
|
"-Dartifactory.staging-repository=${p['artifactory.repository.snapshot']} " +
|
||||||
"-Dartifactory.build-name=spring-data-elasticsearch " +
|
"-Dartifactory.build-name=spring-data-elasticsearch " +
|
||||||
"-Dartifactory.build-number=spring-data-elasticsearch-${BRANCH_NAME}-build-${BUILD_NUMBER} " +
|
"-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"
|
"-Dmaven.test.skip=true clean deploy -U -B"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
changed {
|
changed {
|
||||||
|
@ -2,12 +2,7 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
export DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR}
|
|
||||||
export DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW}
|
|
||||||
export JENKINS_USER=${JENKINS_USER_NAME}
|
export JENKINS_USER=${JENKINS_USER_NAME}
|
||||||
|
|
||||||
# The environment variable to configure access key is still GRADLE_ENTERPRISE_ACCESS_KEY
|
|
||||||
export GRADLE_ENTERPRISE_ACCESS_KEY=${DEVELOCITY_ACCESS_KEY}
|
|
||||||
|
|
||||||
MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
|
MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
|
||||||
./mvnw -s settings.xml clean -Dscan=false -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch
|
./mvnw -s settings.xml clean -Dscan=false -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# Java versions
|
# Java versions
|
||||||
java.main.tag=17.0.9_9-jdk-focal
|
java.main.tag=17.0.13_11-jdk-focal
|
||||||
java.next.tag=21.0.1_12-jdk-jammy
|
java.next.tag=22.0.2_9-jdk-jammy
|
||||||
|
|
||||||
# Docker container images - standard
|
# Docker container images - standard
|
||||||
docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag}
|
docker.java.main.image=library/eclipse-temurin:${java.main.tag}
|
||||||
docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag}
|
docker.java.next.image=library/eclipse-temurin:${java.next.tag}
|
||||||
|
|
||||||
# Supported versions of MongoDB
|
# Supported versions of MongoDB
|
||||||
docker.mongodb.4.4.version=4.4.25
|
docker.mongodb.4.4.version=4.4.25
|
||||||
@ -14,6 +14,7 @@ docker.mongodb.7.0.version=7.0.2
|
|||||||
|
|
||||||
# Supported versions of Redis
|
# Supported versions of Redis
|
||||||
docker.redis.6.version=6.2.13
|
docker.redis.6.version=6.2.13
|
||||||
|
docker.redis.7.version=7.2.4
|
||||||
|
|
||||||
# Supported versions of Cassandra
|
# Supported versions of Cassandra
|
||||||
docker.cassandra.3.version=3.11.16
|
docker.cassandra.3.version=3.11.16
|
||||||
@ -25,9 +26,10 @@ docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -
|
|||||||
# Credentials
|
# Credentials
|
||||||
docker.registry=
|
docker.registry=
|
||||||
docker.credentials=hub.docker.com-springbuildmaster
|
docker.credentials=hub.docker.com-springbuildmaster
|
||||||
|
docker.proxy.registry=https://docker-hub.usw1.packages.broadcom.com
|
||||||
|
docker.proxy.credentials=usw1_packages_broadcom_com-jenkins-token
|
||||||
artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c
|
artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c
|
||||||
artifactory.url=https://repo.spring.io
|
artifactory.url=https://repo.spring.io
|
||||||
artifactory.repository.snapshot=libs-snapshot-local
|
artifactory.repository.snapshot=libs-snapshot-local
|
||||||
develocity.cache.credentials=gradle_enterprise_cache_user
|
|
||||||
develocity.access-key=gradle_enterprise_secret_access_key
|
develocity.access-key=gradle_enterprise_secret_access_key
|
||||||
jenkins.user.name=spring-builds+jenkins
|
jenkins.user.name=spring-builds+jenkins
|
||||||
|
@ -3,15 +3,8 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
mkdir -p /tmp/jenkins-home/.m2/spring-data-elasticsearch
|
mkdir -p /tmp/jenkins-home/.m2/spring-data-elasticsearch
|
||||||
chown -R 1001:1001 .
|
|
||||||
|
|
||||||
export DEVELOCITY_CACHE_USERNAME=${DEVELOCITY_CACHE_USR}
|
|
||||||
export DEVELOCITY_CACHE_PASSWORD=${DEVELOCITY_CACHE_PSW}
|
|
||||||
export JENKINS_USER=${JENKINS_USER_NAME}
|
export JENKINS_USER=${JENKINS_USER_NAME}
|
||||||
|
|
||||||
# The environment variable to configure access key is still GRADLE_ENTERPRISE_ACCESS_KEY
|
|
||||||
export GRADLE_ENTERPRISE_ACCESS_KEY=${DEVELOCITY_ACCESS_KEY}
|
|
||||||
|
|
||||||
MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
|
MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
|
||||||
./mvnw -s settings.xml \
|
./mvnw -s settings.xml \
|
||||||
-P${PROFILE} clean dependency:list verify -Dsort -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch
|
-P${PROFILE} clean dependency:list verify -Dsort -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
|
||||||
|
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"antora": "3.2.0-alpha.6",
|
||||||
|
"@antora/atlas-extension": "1.0.0-alpha.2",
|
||||||
|
"@antora/collector-extension": "1.0.0-alpha.7",
|
||||||
|
"@asciidoctor/tabs": "1.0.0-beta.6",
|
||||||
|
"@springio/antora-extensions": "1.13.0",
|
||||||
|
"@springio/asciidoctor-extensions": "1.0.0-alpha.11"
|
||||||
|
}
|
||||||
|
}
|
37
pom.xml
37
pom.xml
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-elasticsearch</artifactId>
|
<artifactId>spring-data-elasticsearch</artifactId>
|
||||||
<version>5.3.0</version>
|
<version>5.3.7</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data.build</groupId>
|
<groupId>org.springframework.data.build</groupId>
|
||||||
<artifactId>spring-data-parent</artifactId>
|
<artifactId>spring-data-parent</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>3.3.7</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>Spring Data Elasticsearch</name>
|
<name>Spring Data Elasticsearch</name>
|
||||||
@ -18,12 +18,11 @@
|
|||||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<springdata.commons>3.3.0</springdata.commons>
|
<springdata.commons>3.3.7</springdata.commons>
|
||||||
|
|
||||||
<!-- version of the ElasticsearchClient -->
|
<!-- version of the ElasticsearchClient -->
|
||||||
<elasticsearch-java>8.13.2</elasticsearch-java>
|
<elasticsearch-java>8.13.4</elasticsearch-java>
|
||||||
|
|
||||||
<blockhound-junit>1.0.8.RELEASE</blockhound-junit>
|
|
||||||
<hoverfly>0.14.4</hoverfly>
|
<hoverfly>0.14.4</hoverfly>
|
||||||
<log4j>2.18.0</log4j>
|
<log4j>2.18.0</log4j>
|
||||||
<jsonassert>1.5.1</jsonassert>
|
<jsonassert>1.5.1</jsonassert>
|
||||||
@ -248,13 +247,6 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.projectreactor.tools</groupId>
|
|
||||||
<artifactId>blockhound-junit-platform</artifactId>
|
|
||||||
<version>${blockhound-junit}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.skyscreamer</groupId>
|
<groupId>org.skyscreamer</groupId>
|
||||||
<artifactId>jsonassert</artifactId>
|
<artifactId>jsonassert</artifactId>
|
||||||
@ -443,25 +435,6 @@
|
|||||||
</build>
|
</build>
|
||||||
</profile>
|
</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>
|
<profile>
|
||||||
<id>antora-process-resources</id>
|
<id>antora-process-resources</id>
|
||||||
<build>
|
<build>
|
||||||
@ -479,7 +452,7 @@
|
|||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.spring.maven.antora</groupId>
|
<groupId>org.antora</groupId>
|
||||||
<artifactId>antora-maven-plugin</artifactId>
|
<artifactId>antora-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
# The purpose of this Antora playbook is to build the docs in the current branch.
|
# The purpose of this Antora playbook is to build the docs in the current branch.
|
||||||
antora:
|
antora:
|
||||||
extensions:
|
extensions:
|
||||||
- '@antora/collector-extension'
|
- require: '@springio/antora-extensions'
|
||||||
- require: '@springio/antora-extensions/root-component-extension'
|
|
||||||
root_component_name: 'data-elasticsearch'
|
root_component_name: 'data-elasticsearch'
|
||||||
site:
|
site:
|
||||||
title: Spring Data Elasticsearch
|
title: Spring Data Elasticsearch
|
||||||
@ -22,13 +21,12 @@ content:
|
|||||||
start_path: src/main/antora
|
start_path: src/main/antora
|
||||||
asciidoc:
|
asciidoc:
|
||||||
attributes:
|
attributes:
|
||||||
page-pagination: ''
|
|
||||||
hide-uri-scheme: '@'
|
hide-uri-scheme: '@'
|
||||||
tabs-sync-option: '@'
|
tabs-sync-option: '@'
|
||||||
chomp: 'all'
|
|
||||||
extensions:
|
extensions:
|
||||||
- '@asciidoctor/tabs'
|
- '@asciidoctor/tabs'
|
||||||
- '@springio/asciidoctor-extensions'
|
- '@springio/asciidoctor-extensions'
|
||||||
|
- '@springio/asciidoctor-extensions/javadoc-extension'
|
||||||
sourcemap: true
|
sourcemap: true
|
||||||
urls:
|
urls:
|
||||||
latest_version_segment: ''
|
latest_version_segment: ''
|
||||||
@ -38,5 +36,5 @@ runtime:
|
|||||||
format: pretty
|
format: pretty
|
||||||
ui:
|
ui:
|
||||||
bundle:
|
bundle:
|
||||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip
|
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
|
||||||
snapshot: true
|
snapshot: true
|
||||||
|
@ -10,3 +10,8 @@ ext:
|
|||||||
local: true
|
local: true
|
||||||
scan:
|
scan:
|
||||||
dir: target/classes/
|
dir: target/classes/
|
||||||
|
- run:
|
||||||
|
command: ./mvnw package -Pdistribute
|
||||||
|
local: true
|
||||||
|
scan:
|
||||||
|
dir: target/antora
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*** xref:migration-guides/migration-guide-4.4-5.0.adoc[]
|
*** xref:migration-guides/migration-guide-4.4-5.0.adoc[]
|
||||||
*** xref:migration-guides/migration-guide-5.0-5.1.adoc[]
|
*** xref:migration-guides/migration-guide-5.0-5.1.adoc[]
|
||||||
*** xref:migration-guides/migration-guide-5.1-5.2.adoc[]
|
*** xref:migration-guides/migration-guide-5.1-5.2.adoc[]
|
||||||
|
*** xref:migration-guides/migration-guide-5.2-5.3.adoc[]
|
||||||
|
|
||||||
* xref:elasticsearch.adoc[]
|
* xref:elasticsearch.adoc[]
|
||||||
** xref:elasticsearch/clients.adoc[]
|
** xref:elasticsearch/clients.adoc[]
|
||||||
@ -39,4 +39,5 @@
|
|||||||
** xref:repositories/query-keywords-reference.adoc[]
|
** xref:repositories/query-keywords-reference.adoc[]
|
||||||
** xref:repositories/query-return-types-reference.adoc[]
|
** xref:repositories/query-return-types-reference.adoc[]
|
||||||
|
|
||||||
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki]
|
* xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank]
|
||||||
|
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki,role=link-external,window=_blank]
|
||||||
|
@ -31,7 +31,7 @@ public class MyClientConfig extends ElasticsearchConfiguration {
|
|||||||
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
|
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
|
||||||
====
|
====
|
||||||
|
|
||||||
The `ElasticsearchConfiguration` class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
|
The javadoc:org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration[]] class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
|
||||||
|
|
||||||
|
|
||||||
The following beans can then be injected in other Spring components:
|
The following beans can then be injected in other Spring components:
|
||||||
@ -52,13 +52,13 @@ RestClient restClient; <.>
|
|||||||
JsonpMapper jsonpMapper; <.>
|
JsonpMapper jsonpMapper; <.>
|
||||||
----
|
----
|
||||||
|
|
||||||
<.> an implementation of `ElasticsearchOperations`
|
<.> an implementation of javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[]
|
||||||
<.> the `co.elastic.clients.elasticsearch.ElasticsearchClient` that is used.
|
<.> the `co.elastic.clients.elasticsearch.ElasticsearchClient` that is used.
|
||||||
<.> the low level `RestClient` from the Elasticsearch libraries
|
<.> the low level `RestClient` from the Elasticsearch libraries
|
||||||
<.> the `JsonpMapper` user by the Elasticsearch `Transport`
|
<.> the `JsonpMapper` user by the Elasticsearch `Transport`
|
||||||
====
|
====
|
||||||
|
|
||||||
Basically one should just use the `ElasticsearchOperations` to interact with the Elasticsearch cluster.
|
Basically one should just use the javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[] to interact with the Elasticsearch cluster.
|
||||||
When using repositories, this instance is used under the hood as well.
|
When using repositories, this instance is used under the hood as well.
|
||||||
|
|
||||||
[[elasticsearch.clients.reactiverestclient]]
|
[[elasticsearch.clients.reactiverestclient]]
|
||||||
@ -86,7 +86,7 @@ public class MyClientConfig extends ReactiveElasticsearchConfiguration {
|
|||||||
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
|
<.> for a detailed description of the builder methods see xref:elasticsearch/clients.adoc#elasticsearch.clients.configuration[Client Configuration]
|
||||||
====
|
====
|
||||||
|
|
||||||
The `ReactiveElasticsearchConfiguration` class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
|
The javadoc:org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchConfiguration[] class allows further configuration by overriding for example the `jsonpMapper()` or `transportOptions()` methods.
|
||||||
|
|
||||||
The following beans can then be injected in other Spring components:
|
The following beans can then be injected in other Spring components:
|
||||||
|
|
||||||
@ -108,20 +108,20 @@ JsonpMapper jsonpMapper; <.>
|
|||||||
|
|
||||||
the following can be injected:
|
the following can be injected:
|
||||||
|
|
||||||
<.> an implementation of `ReactiveElasticsearchOperations`
|
<.> an implementation of javadoc:org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations[]
|
||||||
<.> the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient` that is used.
|
<.> the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient` that is used.
|
||||||
This is a reactive implementation based on the Elasticsearch client implementation.
|
This is a reactive implementation based on the Elasticsearch client implementation.
|
||||||
<.> the low level `RestClient` from the Elasticsearch libraries
|
<.> the low level `RestClient` from the Elasticsearch libraries
|
||||||
<.> the `JsonpMapper` user by the Elasticsearch `Transport`
|
<.> the `JsonpMapper` user by the Elasticsearch `Transport`
|
||||||
====
|
====
|
||||||
|
|
||||||
Basically one should just use the `ReactiveElasticsearchOperations` to interact with the Elasticsearch cluster.
|
Basically one should just use the javadoc:org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations[] to interact with the Elasticsearch cluster.
|
||||||
When using repositories, this instance is used under the hood as well.
|
When using repositories, this instance is used under the hood as well.
|
||||||
|
|
||||||
[[elasticsearch.clients.configuration]]
|
[[elasticsearch.clients.configuration]]
|
||||||
== Client Configuration
|
== Client Configuration
|
||||||
|
|
||||||
Client behaviour can be changed via the `ClientConfiguration` that allows to set options for SSL, connect and socket timeouts, headers and other parameters.
|
Client behaviour can be changed via the javadoc:org.springframework.data.elasticsearch.client.ClientConfiguration[] that allows to set options for SSL, connect and socket timeouts, headers and other parameters.
|
||||||
|
|
||||||
.Client Configuration
|
.Client Configuration
|
||||||
====
|
====
|
||||||
@ -178,7 +178,7 @@ If this is used in the reactive setup, the supplier function *must not* block!
|
|||||||
[[elasticsearch.clients.configuration.callbacks]]
|
[[elasticsearch.clients.configuration.callbacks]]
|
||||||
=== Client configuration callbacks
|
=== Client configuration callbacks
|
||||||
|
|
||||||
The `ClientConfiguration` class offers the most common parameters to configure the client.
|
The javadoc:org.springframework.data.elasticsearch.client.ClientConfiguration[] class offers the most common parameters to configure the client.
|
||||||
In the case this is not enough, the user can add callback functions by using the `withClientConfigurer(ClientConfigurationCallback<?>)` method.
|
In the case this is not enough, the user can add callback functions by using the `withClientConfigurer(ClientConfigurationCallback<?>)` method.
|
||||||
|
|
||||||
The following callbacks are provided:
|
The following callbacks are provided:
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
[[new-features]]
|
[[new-features]]
|
||||||
= What's new
|
= What's new
|
||||||
|
|
||||||
|
[[new-features.5-3-1]]
|
||||||
|
== New in Spring Data Elasticsearch 5.3.1
|
||||||
|
|
||||||
|
* Upgrade to Elasticsearch 8.13.4.
|
||||||
|
|
||||||
[[new-features.5-3-0]]
|
[[new-features.5-3-0]]
|
||||||
== New in Spring Data Elasticsearch 5.3
|
== New in Spring Data Elasticsearch 5.3
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
Spring Data Elasticsearch uses several interfaces to define the operations that can be called against an Elasticsearch index (for a description of the reactive interfaces see xref:elasticsearch/reactive-template.adoc[]).
|
Spring Data Elasticsearch uses several interfaces to define the operations that can be called against an Elasticsearch index (for a description of the reactive interfaces see xref:elasticsearch/reactive-template.adoc[]).
|
||||||
|
|
||||||
* `IndexOperations` defines actions on index level like creating or deleting an index.
|
* javadoc:org.springframework.data.elasticsearch.core.IndexOperations[] defines actions on index level like creating or deleting an index.
|
||||||
* `DocumentOperations` defines actions to store, update and retrieve entities based on their id.
|
* javadoc:org.springframework.data.elasticsearch.core.DocumentOperations[] defines actions to store, update and retrieve entities based on their id.
|
||||||
* `SearchOperations` define the actions to search for multiple entities using queries
|
* javadoc:org.springframework.data.elasticsearch.core.SearchOperations[] define the actions to search for multiple entities using queries
|
||||||
* `ElasticsearchOperations` combines the `DocumentOperations` and `SearchOperations` interfaces.
|
* javadoc:org.springframework.data.elasticsearch.core.ElasticsearchOperations[] combines the `DocumentOperations` and `SearchOperations` interfaces.
|
||||||
|
|
||||||
These interfaces correspond to the structuring of the https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html[Elasticsearch API].
|
These interfaces correspond to the structuring of the https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html[Elasticsearch API].
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@ The following table shows the Elasticsearch and Spring versions that are used by
|
|||||||
[cols="^,^,^,^",options="header"]
|
[cols="^,^,^,^",options="header"]
|
||||||
|===
|
|===
|
||||||
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
|
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
|
||||||
| 2024.0 (?) | 5.3.x | 8.13.2 | ?
|
| 2024.0 | 5.3.3 | 8.13.4 | 6.1.x
|
||||||
| 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x
|
| 2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x
|
||||||
| 2023.0 (Ullmann) | 5.1.x | 8.7.1 | 6.0.x
|
| 2023.0 (Ullmann) | 5.1.xfootnote:oom[Out of maintenance] | 8.7.1 | 6.0.x
|
||||||
| 2022.0 (Turing) | 5.0.xfootnote:oom[Out of maintenance] | 8.5.3 | 6.0.x
|
| 2022.0 (Turing) | 5.0.xfootnote:oom[] | 8.5.3 | 6.0.x
|
||||||
| 2021.2 (Raj) | 4.4.xfootnote:oom[] | 7.17.3 | 5.3.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.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
|
| 2021.0 (Pascal) | 4.2.xfootnote:oom[] | 7.12.0 | 5.3.x
|
||||||
|
@ -5,7 +5,10 @@ This section describes breaking changes from version 5.2.x to 5.3.x and how remo
|
|||||||
|
|
||||||
[[elasticsearch-migration-guide-5.2-5.3.breaking-changes]]
|
[[elasticsearch-migration-guide-5.2-5.3.breaking-changes]]
|
||||||
== Breaking Changes
|
== Breaking Changes
|
||||||
|
During the parameter replacement in `@Query` annotated repository methods previous versions wrote the String _"null"_ into the query that was sent to Elasticsearch
|
||||||
|
when the actual parameter value was `null`. As Elasticsearch does not store `null` values, this behaviour could lead to problems, for example whent the fields to be
|
||||||
|
searched contains the string `"null"`. In Version 5.3 a `null` value in a parameter will cause a `ConversionException` to be thrown. If you are using `"null"` as the
|
||||||
|
`null_value` defined in a field mapping, then pass that string into the query instead of a Java `null`.
|
||||||
|
|
||||||
[[elasticsearch-migration-guide-5.2-5.3.deprecations]]
|
[[elasticsearch-migration-guide-5.2-5.3.deprecations]]
|
||||||
== Deprecations
|
== Deprecations
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package org.springframework.data.elasticsearch.client.elc;
|
package org.springframework.data.elasticsearch.client.elc;
|
||||||
|
|
||||||
import co.elastic.clients.elasticsearch._types.KnnQuery;
|
import co.elastic.clients.elasticsearch._types.KnnQuery;
|
||||||
|
import co.elastic.clients.elasticsearch._types.KnnSearch;
|
||||||
import co.elastic.clients.elasticsearch._types.SortOptions;
|
import co.elastic.clients.elasticsearch._types.SortOptions;
|
||||||
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
|
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
|
||||||
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
|
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
|
||||||
@ -54,6 +55,7 @@ public class NativeQuery extends BaseQuery {
|
|||||||
|
|
||||||
private Map<String, JsonData> searchExtensions = Collections.emptyMap();
|
private Map<String, JsonData> searchExtensions = Collections.emptyMap();
|
||||||
@Nullable private KnnQuery knnQuery;
|
@Nullable private KnnQuery knnQuery;
|
||||||
|
@Nullable private List<KnnSearch> knnSearches = Collections.emptyList();
|
||||||
|
|
||||||
public NativeQuery(NativeQueryBuilder builder) {
|
public NativeQuery(NativeQueryBuilder builder) {
|
||||||
super(builder);
|
super(builder);
|
||||||
@ -71,6 +73,7 @@ public class NativeQuery extends BaseQuery {
|
|||||||
}
|
}
|
||||||
this.springDataQuery = builder.getSpringDataQuery();
|
this.springDataQuery = builder.getSpringDataQuery();
|
||||||
this.knnQuery = builder.getKnnQuery();
|
this.knnQuery = builder.getKnnQuery();
|
||||||
|
this.knnSearches = builder.getKnnSearches();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NativeQuery(@Nullable Query query) {
|
public NativeQuery(@Nullable Query query) {
|
||||||
@ -129,6 +132,14 @@ public class NativeQuery extends BaseQuery {
|
|||||||
return knnQuery;
|
return knnQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.3.1
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<KnnSearch> getKnnSearches() {
|
||||||
|
return knnSearches;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() {
|
public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() {
|
||||||
return springDataQuery;
|
return springDataQuery;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package org.springframework.data.elasticsearch.client.elc;
|
package org.springframework.data.elasticsearch.client.elc;
|
||||||
|
|
||||||
import co.elastic.clients.elasticsearch._types.KnnQuery;
|
import co.elastic.clients.elasticsearch._types.KnnQuery;
|
||||||
|
import co.elastic.clients.elasticsearch._types.KnnSearch;
|
||||||
import co.elastic.clients.elasticsearch._types.SortOptions;
|
import co.elastic.clients.elasticsearch._types.SortOptions;
|
||||||
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
|
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
|
||||||
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
|
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
|
||||||
@ -26,6 +27,7 @@ import co.elastic.clients.util.ObjectBuilder;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -52,6 +54,7 @@ public class NativeQueryBuilder extends BaseQueryBuilder<NativeQuery, NativeQuer
|
|||||||
|
|
||||||
@Nullable private org.springframework.data.elasticsearch.core.query.Query springDataQuery;
|
@Nullable private org.springframework.data.elasticsearch.core.query.Query springDataQuery;
|
||||||
@Nullable private KnnQuery knnQuery;
|
@Nullable private KnnQuery knnQuery;
|
||||||
|
@Nullable private List<KnnSearch> knnSearches = Collections.emptyList();
|
||||||
|
|
||||||
public NativeQueryBuilder() {}
|
public NativeQueryBuilder() {}
|
||||||
|
|
||||||
@ -92,6 +95,14 @@ public class NativeQueryBuilder extends BaseQueryBuilder<NativeQuery, NativeQuer
|
|||||||
return knnQuery;
|
return knnQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.3.1
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<KnnSearch> getKnnSearches() {
|
||||||
|
return knnSearches;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() {
|
public org.springframework.data.elasticsearch.core.query.Query getSpringDataQuery() {
|
||||||
return springDataQuery;
|
return springDataQuery;
|
||||||
|
@ -395,7 +395,28 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
|||||||
Function<PitSearchAfter, Publisher<? extends ResponseBody<EntityAsMap>>> resourceClosure = psa -> {
|
Function<PitSearchAfter, Publisher<? extends ResponseBody<EntityAsMap>>> resourceClosure = psa -> {
|
||||||
|
|
||||||
baseQuery.setPointInTime(new Query.PointInTime(psa.getPit(), pitKeepAlive));
|
baseQuery.setPointInTime(new Query.PointInTime(psa.getPit(), pitKeepAlive));
|
||||||
|
|
||||||
|
// only add _shard_doc if there is not a field_collapse and a sort with the same name
|
||||||
|
boolean addShardDoc = true;
|
||||||
|
|
||||||
|
if (query instanceof NativeQuery nativeQuery && nativeQuery.getFieldCollapse() != null) {
|
||||||
|
var field = nativeQuery.getFieldCollapse().field();
|
||||||
|
|
||||||
|
if (nativeQuery.getSortOptions().stream()
|
||||||
|
.anyMatch(sortOptions -> sortOptions.isField() && sortOptions.field().field().equals(field))) {
|
||||||
|
addShardDoc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.getSort() != null
|
||||||
|
&& query.getSort().stream().anyMatch(order -> order.getProperty().equals(field))) {
|
||||||
|
addShardDoc = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addShardDoc) {
|
||||||
baseQuery.addSort(Sort.by("_shard_doc"));
|
baseQuery.addSort(Sort.by("_shard_doc"));
|
||||||
|
}
|
||||||
|
|
||||||
SearchRequest firstSearchRequest = requestConverter.searchRequest(baseQuery, routingResolver.getRouting(),
|
SearchRequest firstSearchRequest = requestConverter.searchRequest(baseQuery, routingResolver.getRouting(),
|
||||||
clazz, index, false, true);
|
clazz, index, false, true);
|
||||||
|
|
||||||
|
@ -1021,6 +1021,9 @@ class RequestConverter extends AbstractQueryProcessor {
|
|||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (query.getRefresh() != null) {
|
||||||
|
dqb.refresh(query.getRefresh());
|
||||||
|
}
|
||||||
dqb.allowNoIndices(query.getAllowNoIndices())
|
dqb.allowNoIndices(query.getAllowNoIndices())
|
||||||
.conflicts(conflicts(query.getConflicts()))
|
.conflicts(conflicts(query.getConflicts()))
|
||||||
.ignoreUnavailable(query.getIgnoreUnavailable())
|
.ignoreUnavailable(query.getIgnoreUnavailable())
|
||||||
@ -1477,8 +1480,8 @@ class RequestConverter extends AbstractQueryProcessor {
|
|||||||
if (query instanceof NativeQuery nativeQuery) {
|
if (query instanceof NativeQuery nativeQuery) {
|
||||||
prepareNativeSearch(nativeQuery, builder);
|
prepareNativeSearch(nativeQuery, builder);
|
||||||
}
|
}
|
||||||
// query.getSort() must be checked after prepareNativeSearch as this already might hav a sort set that must have
|
// query.getSort() must be checked after prepareNativeSearch as this already might have a sort set
|
||||||
// higher priority
|
// that must have higher priority
|
||||||
if (query.getSort() != null) {
|
if (query.getSort() != null) {
|
||||||
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
|
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
|
||||||
|
|
||||||
@ -1500,7 +1503,15 @@ class RequestConverter extends AbstractQueryProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmpty(query.getSearchAfter())) {
|
if (!isEmpty(query.getSearchAfter())) {
|
||||||
builder.searchAfter(query.getSearchAfter().stream().map(TypeUtils::toFieldValue).toList());
|
var fieldValues = query.getSearchAfter().stream().map(TypeUtils::toFieldValue).toList();
|
||||||
|
|
||||||
|
// when there is a field collapse on a native query, and we have a search_after, then the search_after
|
||||||
|
// must only have one entry
|
||||||
|
if (query instanceof NativeQuery nativeQuery && nativeQuery.getFieldCollapse() != null) {
|
||||||
|
builder.searchAfter(fieldValues.get(0));
|
||||||
|
} else {
|
||||||
|
builder.searchAfter(fieldValues);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query.getRescorerQueries().forEach(rescorerQuery -> builder.rescore(getRescore(rescorerQuery)));
|
query.getRescorerQueries().forEach(rescorerQuery -> builder.rescore(getRescore(rescorerQuery)));
|
||||||
@ -1719,7 +1730,18 @@ class RequestConverter extends AbstractQueryProcessor {
|
|||||||
;
|
;
|
||||||
|
|
||||||
if (query.getKnnQuery() != null) {
|
if (query.getKnnQuery() != null) {
|
||||||
builder.knn(query.getKnnQuery());
|
var kq = query.getKnnQuery();
|
||||||
|
builder.knn(ksb -> ksb
|
||||||
|
.field(kq.field())
|
||||||
|
.queryVector(kq.queryVector())
|
||||||
|
.numCandidates(kq.numCandidates())
|
||||||
|
.filter(kq.filter())
|
||||||
|
.similarity(kq.similarity()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEmpty(query.getKnnSearches())) {
|
||||||
|
builder.knn(query.getKnnSearches());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmpty(query.getAggregations())) {
|
if (!isEmpty(query.getAggregations())) {
|
||||||
@ -1740,7 +1762,18 @@ class RequestConverter extends AbstractQueryProcessor {
|
|||||||
.sort(query.getSortOptions());
|
.sort(query.getSortOptions());
|
||||||
|
|
||||||
if (query.getKnnQuery() != null) {
|
if (query.getKnnQuery() != null) {
|
||||||
builder.knn(query.getKnnQuery());
|
var kq = query.getKnnQuery();
|
||||||
|
builder.knn(ksb -> ksb
|
||||||
|
.field(kq.field())
|
||||||
|
.queryVector(kq.queryVector())
|
||||||
|
.numCandidates(kq.numCandidates())
|
||||||
|
.filter(kq.filter())
|
||||||
|
.similarity(kq.similarity()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEmpty(query.getKnnSearches())) {
|
||||||
|
builder.knn(query.getKnnSearches());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmpty(query.getAggregations())) {
|
if (!isEmpty(query.getAggregations())) {
|
||||||
|
@ -345,8 +345,10 @@ public class MappingBuilder {
|
|||||||
: nestedPropertyPrefix + '.' + property.getFieldName();
|
: nestedPropertyPrefix + '.' + property.getFieldName();
|
||||||
|
|
||||||
Field fieldAnnotation = property.findAnnotation(Field.class);
|
Field fieldAnnotation = property.findAnnotation(Field.class);
|
||||||
|
MultiField multiFieldAnnotation = property.findAnnotation(MultiField.class);
|
||||||
|
|
||||||
if (fieldAnnotation != null && fieldAnnotation.excludeFromSource()) {
|
if ((fieldAnnotation != null && fieldAnnotation.excludeFromSource()) ||
|
||||||
|
multiFieldAnnotation != null && multiFieldAnnotation.mainField().excludeFromSource()) {
|
||||||
excludeFromSource.add(nestedPropertyPath);
|
excludeFromSource.add(nestedPropertyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,8 +379,6 @@ public class MappingBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiField multiField = property.findAnnotation(MultiField.class);
|
|
||||||
|
|
||||||
if (isCompletionProperty) {
|
if (isCompletionProperty) {
|
||||||
CompletionField completionField = property.findAnnotation(CompletionField.class);
|
CompletionField completionField = property.findAnnotation(CompletionField.class);
|
||||||
applyCompletionFieldMapping(propertiesNode, property, completionField);
|
applyCompletionFieldMapping(propertiesNode, property, completionField);
|
||||||
@ -386,8 +386,8 @@ public class MappingBuilder {
|
|||||||
|
|
||||||
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
|
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
|
||||||
applyDefaultIdFieldMapping(propertiesNode, property);
|
applyDefaultIdFieldMapping(propertiesNode, property);
|
||||||
} else if (multiField != null) {
|
} else if (multiFieldAnnotation != null) {
|
||||||
addMultiFieldMapping(propertiesNode, property, multiField, isNestedOrObjectProperty, dynamicMapping);
|
addMultiFieldMapping(propertiesNode, property, multiFieldAnnotation, isNestedOrObjectProperty, dynamicMapping);
|
||||||
} else if (fieldAnnotation != null) {
|
} else if (fieldAnnotation != null) {
|
||||||
addSingleFieldMapping(propertiesNode, property, fieldAnnotation, isNestedOrObjectProperty, dynamicMapping);
|
addSingleFieldMapping(propertiesNode, property, fieldAnnotation, isNestedOrObjectProperty, dynamicMapping);
|
||||||
}
|
}
|
||||||
|
@ -171,8 +171,8 @@ public final class MappingParameters {
|
|||||||
positiveScoreImpact = field.positiveScoreImpact();
|
positiveScoreImpact = field.positiveScoreImpact();
|
||||||
dims = field.dims();
|
dims = field.dims();
|
||||||
if (type == FieldType.Dense_Vector) {
|
if (type == FieldType.Dense_Vector) {
|
||||||
Assert.isTrue(dims >= 1 && dims <= 2048,
|
Assert.isTrue(dims >= 1 && dims <= 4096,
|
||||||
"Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 2048.");
|
"Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 4096.");
|
||||||
}
|
}
|
||||||
Assert.isTrue(field.enabled() || type == FieldType.Object, "enabled false is only allowed for field type object");
|
Assert.isTrue(field.enabled() || type == FieldType.Object, "enabled false is only allowed for field type object");
|
||||||
enabled = field.enabled();
|
enabled = field.enabled();
|
||||||
@ -214,8 +214,8 @@ public final class MappingParameters {
|
|||||||
positiveScoreImpact = field.positiveScoreImpact();
|
positiveScoreImpact = field.positiveScoreImpact();
|
||||||
dims = field.dims();
|
dims = field.dims();
|
||||||
if (type == FieldType.Dense_Vector) {
|
if (type == FieldType.Dense_Vector) {
|
||||||
Assert.isTrue(dims >= 1 && dims <= 2048,
|
Assert.isTrue(dims >= 1 && dims <= 4096,
|
||||||
"Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 2048.");
|
"Invalid required parameter! Dense_Vector value \"dims\" must be between 1 and 4096.");
|
||||||
}
|
}
|
||||||
enabled = true;
|
enabled = true;
|
||||||
eagerGlobalOrdinals = field.eagerGlobalOrdinals();
|
eagerGlobalOrdinals = field.eagerGlobalOrdinals();
|
||||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.utils.geohash;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ public class Geohash {
|
|||||||
Assert.notNull(geohash, "geohash must not be null");
|
Assert.notNull(geohash, "geohash must not be null");
|
||||||
|
|
||||||
var point = Geohash.toPoint(geohash);
|
var point = Geohash.toPoint(geohash);
|
||||||
return String.format("%f,%f", point.getLat(), point.getLon());
|
return String.format(Locale.ROOT, "%f,%f", point.getLat(), point.getLon());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Spring Data Elasticsearch 5.3 GA (2024.0.0)
|
Spring Data Elasticsearch 5.3.7 (2024.0.7)
|
||||||
Copyright (c) [2013-2022] Pivotal Software, Inc.
|
Copyright (c) [2013-2022] Pivotal Software, Inc.
|
||||||
|
|
||||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
@ -21,4 +21,11 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
* 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.blockhound;
|
|
||||||
|
|
||||||
import reactor.blockhound.BlockHound;
|
|
||||||
import reactor.blockhound.BlockingOperationError;
|
|
||||||
import reactor.blockhound.integration.BlockHoundIntegration;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Peter-Josef Meisch
|
|
||||||
*/
|
|
||||||
public class BlockHoundIntegrationCustomizer implements BlockHoundIntegration {
|
|
||||||
|
|
||||||
private static final Log LOGGER = LogFactory.getLog(BlockHoundIntegrationCustomizer.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(BlockHound.Builder builder) {
|
|
||||||
// Elasticsearch classes reading from the classpath on initialization, needed for parsing Elasticsearch responses
|
|
||||||
builder //
|
|
||||||
.allowBlockingCallsInside("org.elasticsearch.Build", "<clinit>") //
|
|
||||||
.allowBlockingCallsInside("org.elasticsearch.common.xcontent.XContentBuilder", "<clinit>") // pre 7.16
|
|
||||||
.allowBlockingCallsInside("org.elasticsearch.common.XContentBuilder", "<clinit>") // from 7.16 on
|
|
||||||
.allowBlockingCallsInside("org.elasticsearch.xcontent.json.JsonXContent", "contentBuilder") // from 7.16 on
|
|
||||||
.allowBlockingCallsInside("jakarta.json.spi.JsonProvider", "provider") //
|
|
||||||
;
|
|
||||||
builder.blockingMethodCallback(it -> {
|
|
||||||
LOGGER.error("BlockHound error", new Error(it.toString()));
|
|
||||||
throw new BlockingOperationError(it);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
* 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.blockhound;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
|
||||||
|
|
||||||
import reactor.blockhound.BlockingOperationError;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Peter-Josef Meisch
|
|
||||||
*/
|
|
||||||
public class BlockHoundTests {
|
|
||||||
|
|
||||||
@Test // #1822
|
|
||||||
@DisplayName("should fail if BlockHound is not installed")
|
|
||||||
void shouldFailIfBlockHoundIsNotInstalled() {
|
|
||||||
|
|
||||||
assertThatThrownBy(() -> {
|
|
||||||
Mono.delay(Duration.ofMillis(1)).doOnNext(it -> {
|
|
||||||
try {
|
|
||||||
Thread.sleep(10);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}).block(); // should throw an exception about Thread.sleep
|
|
||||||
}).hasCauseInstanceOf(BlockingOperationError.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -30,12 +30,16 @@ import org.springframework.data.elasticsearch.annotations.FieldType;
|
|||||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.DocValueField;
|
import org.springframework.data.elasticsearch.core.query.DocValueField;
|
||||||
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
|
* @author Han Seungwoo
|
||||||
*/
|
*/
|
||||||
class RequestConverterTest {
|
class RequestConverterTest {
|
||||||
|
|
||||||
@ -72,6 +76,19 @@ class RequestConverterTest {
|
|||||||
assertThat(fieldAndFormats.get(1).format()).isEqualTo("format2");
|
assertThat(fieldAndFormats.get(1).format()).isEqualTo("format2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2973
|
||||||
|
@DisplayName("should set refresh based on deleteRequest")
|
||||||
|
void refreshSetByDeleteRequest() {
|
||||||
|
var query = new CriteriaQuery(new Criteria("text").contains("test"));
|
||||||
|
var deleteQuery = DeleteQuery.builder(query).withRefresh(true).build();
|
||||||
|
|
||||||
|
var deleteByQueryRequest = requestConverter.documentDeleteByQueryRequest(deleteQuery, null, SampleEntity.class,
|
||||||
|
IndexCoordinates.of("foo"),
|
||||||
|
null);
|
||||||
|
|
||||||
|
assertThat(deleteByQueryRequest.refresh()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Document(indexName = "does-not-matter")
|
@Document(indexName = "does-not-matter")
|
||||||
static class SampleEntity {
|
static class SampleEntity {
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -1112,15 +1112,26 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
|||||||
"type": "text"
|
"type": "text"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"excluded-multifield": {
|
||||||
|
"type": "text",
|
||||||
|
"fields": {
|
||||||
|
"keyword": {
|
||||||
|
"type": "keyword"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"_source": {
|
"_source": {
|
||||||
"excludes": [
|
"excludes": [
|
||||||
"excluded-date",
|
"excluded-date",
|
||||||
"nestedEntity.excluded-text"
|
"nestedEntity.excluded-text",
|
||||||
|
"excluded-multifield"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"""; //
|
"""; //
|
||||||
|
|
||||||
String mapping = getMappingBuilder().buildPropertyMapping(ExcludedFieldEntity.class);
|
String mapping = getMappingBuilder().buildPropertyMapping(ExcludedFieldEntity.class);
|
||||||
@ -2395,6 +2406,10 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
|||||||
excludeFromSource = true) private LocalDate excludedDate;
|
excludeFromSource = true) private LocalDate excludedDate;
|
||||||
@Nullable
|
@Nullable
|
||||||
@Field(type = Nested) private NestedExcludedFieldEntity nestedEntity;
|
@Field(type = Nested) private NestedExcludedFieldEntity nestedEntity;
|
||||||
|
@Nullable
|
||||||
|
@MultiField(mainField = @Field(name = "excluded-multifield", type = Text, excludeFromSource = true), otherFields = {
|
||||||
|
@InnerField(suffix = "keyword", type = Keyword)
|
||||||
|
}) private String excludedMultifield;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -70,8 +70,8 @@ public class MappingParametersTest extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test // #1700
|
@Test // #1700
|
||||||
@DisplayName("should not allow dims length greater than 2048 for dense_vector type")
|
@DisplayName("should not allow dims length greater than 4096 for dense_vector type")
|
||||||
void shouldNotAllowDimsLengthGreaterThan2048ForDenseVectorType() {
|
void shouldNotAllowDimsLengthGreaterThan4096ForDenseVectorType() {
|
||||||
ElasticsearchPersistentEntity<?> failEntity = elasticsearchConverter.get().getMappingContext()
|
ElasticsearchPersistentEntity<?> failEntity = elasticsearchConverter.get().getMappingContext()
|
||||||
.getRequiredPersistentEntity(DenseVectorInvalidDimsClass.class);
|
.getRequiredPersistentEntity(DenseVectorInvalidDimsClass.class);
|
||||||
Annotation annotation = failEntity.getRequiredPersistentProperty("dense_vector").findAnnotation(Field.class);
|
Annotation annotation = failEntity.getRequiredPersistentProperty("dense_vector").findAnnotation(Field.class);
|
||||||
@ -90,21 +90,28 @@ public class MappingParametersTest extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class AnnotatedClass {
|
static class AnnotatedClass {
|
||||||
@Nullable @Field private String field;
|
@Nullable
|
||||||
@Nullable @MultiField(mainField = @Field,
|
@Field private String field;
|
||||||
|
@Nullable
|
||||||
|
@MultiField(mainField = @Field,
|
||||||
otherFields = { @InnerField(suffix = "test", type = FieldType.Text) }) private String mainField;
|
otherFields = { @InnerField(suffix = "test", type = FieldType.Text) }) private String mainField;
|
||||||
@Nullable @Field(type = FieldType.Text, docValues = false) private String docValuesText;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Nested, docValues = false) private String docValuesNested;
|
@Field(type = FieldType.Text, docValues = false) private String docValuesText;
|
||||||
@Nullable @Field(type = Object, enabled = true) private String enabledObject;
|
@Nullable
|
||||||
@Nullable @Field(type = Object, enabled = false) private String disabledObject;
|
@Field(type = FieldType.Nested, docValues = false) private String docValuesNested;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = Object, enabled = true) private String enabledObject;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = Object, enabled = false) private String disabledObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class InvalidEnabledFieldClass {
|
static class InvalidEnabledFieldClass {
|
||||||
@Nullable @Field(type = FieldType.Text, enabled = false) private String disabledObject;
|
@Nullable
|
||||||
|
@Field(type = FieldType.Text, enabled = false) private String disabledObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DenseVectorInvalidDimsClass {
|
static class DenseVectorInvalidDimsClass {
|
||||||
@Field(type = Dense_Vector, dims = 2049) private float[] dense_vector;
|
@Field(type = Dense_Vector, dims = 4097) private float[] dense_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DenseVectorMissingDimsClass {
|
static class DenseVectorMissingDimsClass {
|
||||||
|
@ -132,7 +132,7 @@ public class ClusterConnection implements ExtensionContext.Store.CloseableResour
|
|||||||
DockerImageName dockerImageName = getDockerImageName(testcontainersProperties);
|
DockerImageName dockerImageName = getDockerImageName(testcontainersProperties);
|
||||||
|
|
||||||
ElasticsearchContainer elasticsearchContainer = new SpringDataElasticsearchContainer(dockerImageName)
|
ElasticsearchContainer elasticsearchContainer = new SpringDataElasticsearchContainer(dockerImageName)
|
||||||
.withEnv(testcontainersProperties).withStartupTimeout(Duration.ofMinutes(2));
|
.withEnv(testcontainersProperties).withStartupTimeout(Duration.ofMinutes(2)).withReuse(true);
|
||||||
elasticsearchContainer.start();
|
elasticsearchContainer.start();
|
||||||
|
|
||||||
return ClusterConnectionInfo.builder() //
|
return ClusterConnectionInfo.builder() //
|
||||||
@ -192,16 +192,7 @@ public class ClusterConnection implements ExtensionContext.Store.CloseableResour
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
|
||||||
if (clusterConnectionInfo != null && clusterConnectionInfo.getElasticsearchContainer() != null) {
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug("Stopping container");
|
|
||||||
}
|
|
||||||
clusterConnectionInfo.getElasticsearchContainer().stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug("closed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SpringDataElasticsearchContainer extends ElasticsearchContainer {
|
private static class SpringDataElasticsearchContainer extends ElasticsearchContainer {
|
||||||
|
@ -15,14 +15,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch.repository.support;
|
package org.springframework.data.elasticsearch.repository.support;
|
||||||
|
|
||||||
|
import co.elastic.clients.elasticsearch.core.search.FieldCollapse;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
|
||||||
|
import org.springframework.data.elasticsearch.client.elc.Queries;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
|
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
|
||||||
import org.springframework.data.elasticsearch.repositories.custommethod.QueryParameter;
|
import org.springframework.data.elasticsearch.repositories.custommethod.QueryParameter;
|
||||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||||
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
|
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
@ -51,4 +59,33 @@ public class SimpleReactiveElasticsearchRepositoryELCIntegrationTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search_after is used by the reactive search operation, it normally always adds _shard_doc as a tiebreaker sort
|
||||||
|
* parameter. This must not be done when a collapse field is used as sort field, as in that case the collapse field
|
||||||
|
* must be the only sort field.
|
||||||
|
*/
|
||||||
|
@Test // #2935
|
||||||
|
@DisplayName("should use collapse_field for search_after in pit search")
|
||||||
|
void shouldUseCollapseFieldForSearchAfterI() {
|
||||||
|
var entity = new SampleEntity();
|
||||||
|
entity.setId("42");
|
||||||
|
entity.setMessage("m");
|
||||||
|
entity.setKeyword("kw");
|
||||||
|
repository.save(entity).block();
|
||||||
|
|
||||||
|
var query = NativeQuery.builder()
|
||||||
|
.withQuery(Queries.matchAllQueryAsQuery())
|
||||||
|
.withPageable(Pageable.unpaged())
|
||||||
|
.withFieldCollapse(FieldCollapse.of(fcb -> fcb
|
||||||
|
.field("keyword")))
|
||||||
|
.withSort(Sort.by("keyword"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
operations.search(query, SampleEntity.class)
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.expectNextCount(1)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
org.springframework.data.elasticsearch.blockhound.BlockHoundIntegrationCustomizer
|
|
@ -15,7 +15,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
|
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
|
||||||
sde.testcontainers.image-version=8.13.2
|
sde.testcontainers.image-version=8.13.4
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13
|
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13
|
||||||
|
Loading…
x
Reference in New Issue
Block a user