Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 08ed5b724d | |||
| 12b869e9dd | |||
| d35dd313b1 | |||
| f65d557689 | |||
| 1c4332dd12 | |||
| b21bd796f6 | |||
| 16eefb6f60 | |||
| 7ebc4ee13a | |||
| a065ba6a76 | |||
| 631e5fe496 | |||
| b1e6e51e16 | |||
| d5df3bfd20 | |||
| 7f390845d3 | |||
| 868a994e33 | |||
| 7d9e6a5a2a | |||
| b34ed6fd2b | |||
| ff4e07d350 | |||
| ede29781da | |||
| 53a7af879a | |||
| c7512fb325 | |||
| b4fde9d48b | |||
| 8e56ef77b8 | |||
| a2a4114d9c | |||
| ec8401a2fb | |||
| 19ec05dae3 | |||
| 70d2de7eec | |||
| 1666fcee02 | |||
| c513a0c03e | |||
| 22fe50c73a | |||
| ef90755c27 | |||
| 9153d4dff4 | |||
| 9109dfa257 | |||
| 64eee02b85 | |||
| 31365fb722 | |||
| c218c1d5e3 | |||
| 5bce5dd880 | |||
| 32c4c4d03f | |||
| 5102d98e10 | |||
| 57a4b755c1 | |||
| edaae2a4e8 | |||
| 4747caf57a | |||
| aba2ff6f5c | |||
| 0dc2902cab | |||
| 3c60e5f9cc | |||
| ef822355ac | |||
| 94d23a1403 | |||
| 13b4d62031 | |||
| 1087b0355f | |||
| 22ed898d63 | |||
| a474a0f533 | |||
| 1d23fb14fa | |||
| e1741ca255 | |||
| 3e4477af16 | |||
| 2244f855f3 | |||
| 03265a4551 | |||
| fdc03cf29e | |||
| e1da43ca9f | |||
| 4a1a4d3851 | |||
| a9ee467455 | |||
| ebccb34db1 | |||
| d1e349f689 | |||
| b8722bab84 | |||
| 9e35f70833 | |||
| 59f3a6b120 | |||
| e534e952a1 | |||
| 868a9d049a | |||
| 28727c6b36 |
+2
-2
@@ -1,3 +1,3 @@
|
||||
#Mon Feb 20 11:59:41 CET 2023
|
||||
#Wed Oct 04 18:24:26 PDT 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.0/apache-maven-3.9.0-bin.zip
|
||||
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
|
||||
|
||||
Vendored
+43
-24
@@ -1,7 +1,7 @@
|
||||
def p = [:]
|
||||
node {
|
||||
checkout scm
|
||||
p = readProperties interpolate: true, file: 'ci/pipeline.properties'
|
||||
checkout scm
|
||||
p = readProperties interpolate: true, file: 'ci/pipeline.properties'
|
||||
}
|
||||
|
||||
pipeline {
|
||||
@@ -18,7 +18,7 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("test: baseline (Java 17)") {
|
||||
stage("test: baseline (main)") {
|
||||
when {
|
||||
beforeAgent(true)
|
||||
anyOf {
|
||||
@@ -32,17 +32,42 @@ pipeline {
|
||||
options { timeout(time: 30, unit: 'MINUTES') }
|
||||
|
||||
environment {
|
||||
DOCKER_HUB = credentials("${p['docker.credentials']}")
|
||||
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
|
||||
sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
|
||||
sh 'PROFILE=none ci/verify.sh'
|
||||
sh "ci/clean.sh"
|
||||
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
|
||||
sh 'PROFILE=none ci/verify.sh'
|
||||
sh "ci/clean.sh"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("Test other configurations") {
|
||||
when {
|
||||
beforeAgent(true)
|
||||
allOf {
|
||||
branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP")
|
||||
not { triggeredBy 'UpstreamCause' }
|
||||
}
|
||||
}
|
||||
parallel {
|
||||
stage("test: baseline (next)") {
|
||||
agent {
|
||||
label 'data'
|
||||
}
|
||||
options { timeout(time: 30, unit: 'MINUTES') }
|
||||
environment {
|
||||
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) {
|
||||
sh 'PROFILE=none ci/verify.sh'
|
||||
sh "ci/clean.sh"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,17 +93,15 @@ pipeline {
|
||||
|
||||
steps {
|
||||
script {
|
||||
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
|
||||
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch-non-root ' +
|
||||
'-Dartifactory.server=https://repo.spring.io ' +
|
||||
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
|
||||
"-Dartifactory.staging-repository=libs-snapshot-local " +
|
||||
"-Dartifactory.build-name=spring-data-elasticsearch " +
|
||||
"-Dartifactory.build-number=${BUILD_NUMBER} " +
|
||||
'-Dmaven.test.skip=true clean deploy -U -B'
|
||||
}
|
||||
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
|
||||
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-elasticsearch-non-root ' +
|
||||
'-Dartifactory.server=https://repo.spring.io ' +
|
||||
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
|
||||
"-Dartifactory.staging-repository=libs-snapshot-local " +
|
||||
"-Dartifactory.build-name=spring-data-elasticsearch " +
|
||||
"-Dartifactory.build-number=${BUILD_NUMBER} " +
|
||||
'-Dmaven.test.skip=true clean deploy -U -B'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,10 +111,6 @@ pipeline {
|
||||
post {
|
||||
changed {
|
||||
script {
|
||||
slackSend(
|
||||
color: (currentBuild.currentResult == 'SUCCESS') ? 'good' : 'danger',
|
||||
channel: '#spring-data-dev',
|
||||
message: "${currentBuild.fullDisplayName} - `${currentBuild.currentResult}`\n${env.BUILD_URL}")
|
||||
emailext(
|
||||
subject: "[${currentBuild.fullDisplayName}] ${currentBuild.currentResult}",
|
||||
mimeType: 'text/html',
|
||||
|
||||
+4
-4
@@ -137,9 +137,9 @@ To use the Release candidate versions of the upcoming major version, use our Mav
|
||||
</dependency>
|
||||
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
----
|
||||
|
||||
@@ -154,9 +154,9 @@ If you'd rather like the latest snapshots of the upcoming major version, use our
|
||||
</dependency>
|
||||
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
----
|
||||
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
# Java versions
|
||||
java.main.tag=17.0.6_10-jdk-focal
|
||||
java.main.tag=17.0.8_7-jdk-focal
|
||||
java.next.tag=20-jdk-jammy
|
||||
|
||||
# Docker container images - standard
|
||||
docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag}
|
||||
docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag}
|
||||
|
||||
# Supported versions of MongoDB
|
||||
docker.mongodb.4.4.version=4.4.18
|
||||
docker.mongodb.5.0.version=5.0.14
|
||||
docker.mongodb.6.0.version=6.0.4
|
||||
docker.mongodb.4.4.version=4.4.25
|
||||
docker.mongodb.5.0.version=5.0.21
|
||||
docker.mongodb.6.0.version=6.0.10
|
||||
|
||||
# Supported versions of Redis
|
||||
docker.redis.6.version=6.2.10
|
||||
docker.redis.6.version=6.2.13
|
||||
|
||||
# Supported versions of Cassandra
|
||||
docker.cassandra.3.version=3.11.14
|
||||
docker.cassandra.3.version=3.11.16
|
||||
|
||||
# Docker environment settings
|
||||
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>5.0.3</version>
|
||||
<version>5.0.11</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<version>3.0.11</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
@@ -18,17 +18,17 @@
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
|
||||
<properties>
|
||||
<springdata.commons>3.0.3</springdata.commons>
|
||||
<springdata.commons>3.0.11</springdata.commons>
|
||||
|
||||
<!-- version of the RestHighLevelClient -->
|
||||
<elasticsearch-rhlc>7.17.9</elasticsearch-rhlc>
|
||||
<elasticsearch-rhlc>7.17.14</elasticsearch-rhlc>
|
||||
<!-- version of the new ElasticsearchClient -->
|
||||
<elasticsearch-java>8.5.3</elasticsearch-java>
|
||||
|
||||
<log4j>2.18.0</log4j>
|
||||
<netty>4.1.65.Final</netty>
|
||||
|
||||
<blockhound-junit>1.0.6.RELEASE</blockhound-junit>
|
||||
<blockhound-junit>1.0.7.RELEASE</blockhound-junit>
|
||||
<hoverfly>0.14.3</hoverfly>
|
||||
<jsonassert>1.5.1</jsonassert>
|
||||
<testcontainers>1.17.3</testcontainers>
|
||||
@@ -279,24 +279,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--
|
||||
we don't use lombok in Spring Data Elasticsearch anymore. But the dependency is set in the parent project, and so the
|
||||
lombok compiler stuff is executed regardless of the fact that we don't need it.
|
||||
On AdoptOpenJdk 16.0.0 this leads to an error, so the project does not build.
|
||||
Therefore we replace lombok with a jar - that just contains an empty file - that lives in a local maven repository in
|
||||
src/test/resources/local-maven-repo/
|
||||
It was installed with
|
||||
mvn deploy:deploy-file -DgroupId=org.projectlombok -DartifactId=lombok -Dversion=999999 -Durl=file:./src/test/resources/local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=path/to/empty.jar
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<!--suppress MavenPackageUpdate -->
|
||||
<version>999999</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
@@ -466,7 +448,7 @@
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
@@ -519,23 +501,8 @@
|
||||
</profiles>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-release</id>
|
||||
<url>https://repo.spring.io/libs-release</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>local-maven-repo</id>
|
||||
<url>file:///${project.basedir}/src/test/resources/local-maven-repo</url>
|
||||
</repository>
|
||||
|
||||
|
||||
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>https://repo.spring.io/plugins-release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -17,9 +17,9 @@ include::reference/elasticsearch-new.adoc[leveloffset=+1]
|
||||
* Version Control - https://github.com/spring-projects/spring-data-elasticsearch
|
||||
* API Documentation - https://docs.spring.io/spring-data/elasticsearch/docs/current/api/
|
||||
* Bugtracker - https://github.com/spring-projects/spring-data-elasticsearch/issues
|
||||
* Release repository - https://repo.spring.io/libs-release
|
||||
* Milestone repository - https://repo.spring.io/libs-milestone
|
||||
* Snapshot repository - https://repo.spring.io/libs-snapshot
|
||||
* Release repository - https://repo1.maven.org/maven2/
|
||||
* Milestone repository - https://repo.spring.io/milestone/
|
||||
* Snapshot repository - https://repo.spring.io/snapshot/
|
||||
|
||||
[[preface.requirements]]
|
||||
== Requirements
|
||||
|
||||
@@ -154,7 +154,7 @@ The old deprecated `RestHighLevelClient` can still be used, but you will need to
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>elasticsearch-rest-high-level-client</artifactId>
|
||||
<version>7.17.9</version>
|
||||
<version>7.17.12</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
@@ -165,4 +165,4 @@ The old deprecated `RestHighLevelClient` can still be used, but you will need to
|
||||
----
|
||||
====
|
||||
|
||||
Make sure to specify the version 7.17.9 explicitly, otherwise maven will resolve to 8.5.3, and this does not exist.
|
||||
Make sure to specify the version 7.17.12 explicitly, otherwise maven will resolve to 8.5.3, and this does not exist.
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ public class NativeQueryBuilder extends BaseQueryBuilder<NativeQuery, NativeQuer
|
||||
|
||||
Assert.notNull(searchExtensions, "searchExtensions must not be null");
|
||||
|
||||
searchExtensions.putAll(searchExtensions);
|
||||
this.searchExtensions.putAll(searchExtensions);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+16
-59
@@ -15,15 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.client.elc;
|
||||
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.searchType;
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.slices;
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.time;
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.timeStringMs;
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.toFloat;
|
||||
import static org.springframework.util.CollectionUtils.isEmpty;
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
|
||||
import static org.springframework.util.CollectionUtils.*;
|
||||
|
||||
import co.elastic.clients.elasticsearch._types.Conflicts;
|
||||
import co.elastic.clients.elasticsearch._types.FieldValue;
|
||||
import co.elastic.clients.elasticsearch._types.InlineScript;
|
||||
import co.elastic.clients.elasticsearch._types.OpType;
|
||||
import co.elastic.clients.elasticsearch._types.SortOptions;
|
||||
@@ -37,18 +32,7 @@ import co.elastic.clients.elasticsearch._types.mapping.RuntimeFieldType;
|
||||
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.Like;
|
||||
import co.elastic.clients.elasticsearch.cluster.HealthRequest;
|
||||
import co.elastic.clients.elasticsearch.core.BulkRequest;
|
||||
import co.elastic.clients.elasticsearch.core.ClosePointInTimeRequest;
|
||||
import co.elastic.clients.elasticsearch.core.DeleteByQueryRequest;
|
||||
import co.elastic.clients.elasticsearch.core.DeleteRequest;
|
||||
import co.elastic.clients.elasticsearch.core.GetRequest;
|
||||
import co.elastic.clients.elasticsearch.core.IndexRequest;
|
||||
import co.elastic.clients.elasticsearch.core.MgetRequest;
|
||||
import co.elastic.clients.elasticsearch.core.MsearchRequest;
|
||||
import co.elastic.clients.elasticsearch.core.OpenPointInTimeRequest;
|
||||
import co.elastic.clients.elasticsearch.core.SearchRequest;
|
||||
import co.elastic.clients.elasticsearch.core.UpdateByQueryRequest;
|
||||
import co.elastic.clients.elasticsearch.core.UpdateRequest;
|
||||
import co.elastic.clients.elasticsearch.core.*;
|
||||
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
|
||||
import co.elastic.clients.elasticsearch.core.bulk.CreateOperation;
|
||||
import co.elastic.clients.elasticsearch.core.bulk.IndexOperation;
|
||||
@@ -58,17 +42,8 @@ import co.elastic.clients.elasticsearch.core.msearch.MultisearchBody;
|
||||
import co.elastic.clients.elasticsearch.core.search.Highlight;
|
||||
import co.elastic.clients.elasticsearch.core.search.Rescore;
|
||||
import co.elastic.clients.elasticsearch.core.search.SourceConfig;
|
||||
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.*;
|
||||
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.GetAliasRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.GetIndexRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.GetIndicesSettingsRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.GetMappingRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.IndexSettings;
|
||||
import co.elastic.clients.elasticsearch.indices.PutMappingRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.RefreshRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.UpdateAliasesRequest;
|
||||
import co.elastic.clients.elasticsearch.indices.update_aliases.Action;
|
||||
import co.elastic.clients.json.JsonData;
|
||||
import co.elastic.clients.json.JsonpDeserializer;
|
||||
@@ -85,7 +60,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
@@ -107,19 +81,7 @@ import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.BulkOptions;
|
||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.Order;
|
||||
import org.springframework.data.elasticsearch.core.query.Query;
|
||||
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.ScriptData;
|
||||
import org.springframework.data.elasticsearch.core.query.SourceFilter;
|
||||
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.*;
|
||||
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
|
||||
import org.springframework.data.elasticsearch.core.reindex.Remote;
|
||||
import org.springframework.data.elasticsearch.support.DefaultStringObjectMap;
|
||||
@@ -918,7 +880,7 @@ class RequestConverter {
|
||||
.docAsUpsert(query.getDocAsUpsert()) //
|
||||
.ifSeqNo(query.getIfSeqNo() != null ? Long.valueOf(query.getIfSeqNo()) : null) //
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm() != null ? Long.valueOf(query.getIfPrimaryTerm()) : null) //
|
||||
.refresh(TypeUtils.refresh(refreshPolicy)) //
|
||||
.refresh(query.getRefreshPolicy() != null ? refresh(query.getRefreshPolicy()) : refresh(refreshPolicy)) //
|
||||
.retryOnConflict(query.getRetryOnConflict()) //
|
||||
;
|
||||
|
||||
@@ -1121,8 +1083,7 @@ class RequestConverter {
|
||||
}
|
||||
|
||||
if (!isEmpty(query.getSearchAfter())) {
|
||||
bb.searchAfter(query.getSearchAfter().stream().map(it -> FieldValue.of(it.toString()))
|
||||
.collect(Collectors.toList()));
|
||||
bb.searchAfter(query.getSearchAfter().stream().map(TypeUtils::toFieldValue).toList());
|
||||
}
|
||||
|
||||
query.getRescorerQueries().forEach(rescorerQuery -> bb.rescore(getRescore(rescorerQuery)));
|
||||
@@ -1146,11 +1107,9 @@ class RequestConverter {
|
||||
}
|
||||
|
||||
if (!isEmpty(query.getIndicesBoost())) {
|
||||
Map<String, Double> boosts = new LinkedHashMap<>();
|
||||
query.getIndicesBoost()
|
||||
.forEach(indexBoost -> boosts.put(indexBoost.getIndexName(), (double) indexBoost.getBoost()));
|
||||
// noinspection unchecked
|
||||
bb.indicesBoost(boosts);
|
||||
bb.indicesBoost(query.getIndicesBoost().stream()
|
||||
.map(indexBoost -> Map.of(indexBoost.getIndexName(), Double.valueOf(indexBoost.getBoost())))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
if (query instanceof NativeQuery) {
|
||||
@@ -1263,8 +1222,7 @@ class RequestConverter {
|
||||
}
|
||||
|
||||
if (!isEmpty(query.getSearchAfter())) {
|
||||
builder.searchAfter(
|
||||
query.getSearchAfter().stream().map(it -> FieldValue.of(it.toString())).collect(Collectors.toList()));
|
||||
builder.searchAfter(query.getSearchAfter().stream().map(TypeUtils::toFieldValue).toList());
|
||||
}
|
||||
|
||||
query.getRescorerQueries().forEach(rescorerQuery -> builder.rescore(getRescore(rescorerQuery)));
|
||||
@@ -1301,11 +1259,9 @@ class RequestConverter {
|
||||
}
|
||||
|
||||
if (!isEmpty(query.getIndicesBoost())) {
|
||||
Map<String, Double> boosts = new LinkedHashMap<>();
|
||||
query.getIndicesBoost()
|
||||
.forEach(indexBoost -> boosts.put(indexBoost.getIndexName(), (double) indexBoost.getBoost()));
|
||||
// noinspection unchecked
|
||||
builder.indicesBoost(boosts);
|
||||
builder.indicesBoost(query.getIndicesBoost().stream()
|
||||
.map(indexBoost -> Map.of(indexBoost.getIndexName(), Double.valueOf(indexBoost.getBoost())))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,9 +1329,10 @@ class RequestConverter {
|
||||
return SortOptions.of(so -> so //
|
||||
.geoDistance(gd -> gd //
|
||||
.field(fieldName) //
|
||||
.location(loc -> loc.latlon(QueryBuilders.latLon(geoDistanceOrder.getGeoPoint())))//
|
||||
.location(loc -> loc.latlon(QueryBuilders.latLon(geoDistanceOrder.getGeoPoint()))) //
|
||||
.distanceType(TypeUtils.geoDistanceType(geoDistanceOrder.getDistanceType()))
|
||||
.mode(TypeUtils.sortMode(finalMode)) //
|
||||
.order(TypeUtils.sortOrder(geoDistanceOrder.getDirection())) //
|
||||
.unit(TypeUtils.distanceUnit(geoDistanceOrder.getUnit())) //
|
||||
.ignoreUnmapped(geoDistanceOrder.getIgnoreUnmapped())));
|
||||
} else {
|
||||
|
||||
+2
-1
@@ -192,7 +192,8 @@ class SearchDocumentResponseBuilder {
|
||||
var phraseSuggestOptions = phraseSuggest.options();
|
||||
List<PhraseSuggestion.Entry.Option> options = new ArrayList<>();
|
||||
phraseSuggestOptions.forEach(optionES -> options
|
||||
.add(new PhraseSuggestion.Entry.Option(optionES.text(), optionES.highlighted(), null, null)));
|
||||
.add(new PhraseSuggestion.Entry.Option(optionES.text(), optionES.highlighted(), optionES.score(),
|
||||
optionES.collateMatch())));
|
||||
entries.add(new PhraseSuggestion.Entry(phraseSuggest.text(), phraseSuggest.offset(), phraseSuggest.length(),
|
||||
options, null));
|
||||
});
|
||||
|
||||
@@ -24,9 +24,11 @@ import co.elastic.clients.elasticsearch.core.search.HighlighterOrder;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterTagsSchema;
|
||||
import co.elastic.clients.elasticsearch.core.search.HighlighterType;
|
||||
import co.elastic.clients.elasticsearch.core.search.ScoreMode;
|
||||
import co.elastic.clients.json.JsonData;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.RefreshPolicy;
|
||||
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
@@ -126,6 +128,40 @@ final class TypeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static FieldValue toFieldValue(@Nullable Object fieldValue) {
|
||||
|
||||
if (fieldValue == null) {
|
||||
return FieldValue.NULL;
|
||||
}
|
||||
|
||||
if (fieldValue instanceof Boolean b) {
|
||||
return b ? FieldValue.TRUE : FieldValue.FALSE;
|
||||
}
|
||||
|
||||
if (fieldValue instanceof String s) {
|
||||
return FieldValue.of(s);
|
||||
}
|
||||
|
||||
if (fieldValue instanceof Long l) {
|
||||
return FieldValue.of(l);
|
||||
}
|
||||
|
||||
if (fieldValue instanceof Integer i) {
|
||||
return FieldValue.of((long) i);
|
||||
}
|
||||
|
||||
if (fieldValue instanceof Double d) {
|
||||
return FieldValue.of(d);
|
||||
}
|
||||
|
||||
if (fieldValue instanceof Float f) {
|
||||
return FieldValue.of((double) f);
|
||||
}
|
||||
|
||||
return FieldValue.of(JsonData.of(fieldValue));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static GeoDistanceType geoDistanceType(GeoDistanceOrder.DistanceType distanceType) {
|
||||
|
||||
@@ -136,6 +172,20 @@ final class TypeUtils {
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static SortOrder sortOrder(@Nullable Sort.Direction direction) {
|
||||
|
||||
if (direction == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return switch (direction) {
|
||||
case ASC -> SortOrder.Asc;
|
||||
case DESC -> SortOrder.Desc;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlighterFragmenter highlighterFragmenter(@Nullable String value) {
|
||||
|
||||
|
||||
@@ -963,6 +963,8 @@ class RequestFactory {
|
||||
sort.ignoreUnmapped(geoDistanceOrder.getIgnoreUnmapped());
|
||||
}
|
||||
|
||||
sort.order(order.isAscending() ? SortOrder.ASC : SortOrder.DESC);
|
||||
|
||||
return sort;
|
||||
} else {
|
||||
FieldSortBuilder sort = SortBuilders //
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.util.Assert;
|
||||
* @author Roman Puchkovskiy
|
||||
* @author Matt Gilene
|
||||
* @author Sascha Woo
|
||||
* @author Jakob Hoeper
|
||||
* @since 4.0
|
||||
*/
|
||||
public class SearchHitMapping<T> {
|
||||
@@ -199,9 +200,10 @@ public class SearchHitMapping<T> {
|
||||
}
|
||||
|
||||
try {
|
||||
ElasticsearchPersistentEntity<?> persistentEntityForType = mappingContext.getPersistentEntity(type);
|
||||
NestedMetaData nestedMetaData = searchHits.getSearchHit(0).getContent().getNestedMetaData();
|
||||
ElasticsearchPersistentEntityWithNestedMetaData persistentEntityWithNestedMetaData = getPersistentEntity(
|
||||
mappingContext.getPersistentEntity(type), nestedMetaData);
|
||||
persistentEntityForType, nestedMetaData);
|
||||
|
||||
if (persistentEntityWithNestedMetaData.entity != null) {
|
||||
List<SearchHit<Object>> convertedSearchHits = new ArrayList<>();
|
||||
@@ -219,7 +221,8 @@ public class SearchHitMapping<T> {
|
||||
searchDocument.getSortValues(), //
|
||||
searchDocument.getHighlightFields(), //
|
||||
searchHit.getInnerHits(), //
|
||||
persistentEntityWithNestedMetaData.nestedMetaData, //
|
||||
getPersistentEntity(persistentEntityForType, //
|
||||
searchHit.getContent().getNestedMetaData()).nestedMetaData, //
|
||||
searchHit.getExplanation(), //
|
||||
searchHit.getMatchedQueries(), //
|
||||
targetObject));
|
||||
|
||||
+11
-5
@@ -32,9 +32,19 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
|
||||
protected static final String LTE_FIELD = "lte";
|
||||
protected static final String GT_FIELD = "gt";
|
||||
protected static final String GTE_FIELD = "gte";
|
||||
private final Class<?> genericType;
|
||||
|
||||
public AbstractRangePropertyValueConverter(PersistentProperty<?> property) {
|
||||
/**
|
||||
* @param property the property this convertrer belongs to
|
||||
* @param genericType the generic type of the Range
|
||||
*/
|
||||
public AbstractRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
|
||||
super(property);
|
||||
this.genericType = genericType;
|
||||
}
|
||||
|
||||
public Class<?> getGenericType() {
|
||||
return genericType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,10 +127,6 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
|
||||
|
||||
protected abstract String format(T value);
|
||||
|
||||
protected Class<?> getGenericType() {
|
||||
return getProperty().getTypeInformation().getTypeArguments().get(0).getType();
|
||||
}
|
||||
|
||||
protected abstract T parse(String value);
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -33,9 +33,9 @@ public class DateRangePropertyValueConverter extends AbstractRangePropertyValueC
|
||||
private final List<ElasticsearchDateConverter> dateConverters;
|
||||
|
||||
public DateRangePropertyValueConverter(PersistentProperty<?> property,
|
||||
List<ElasticsearchDateConverter> dateConverters) {
|
||||
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {
|
||||
|
||||
super(property);
|
||||
super(property, genericType);
|
||||
this.dateConverters = dateConverters;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -919,7 +919,7 @@ public class MappingElasticsearchConverter
|
||||
|
||||
Class<?> elementType = element == null ? null : element.getClass();
|
||||
|
||||
if (elementType == null || conversions.isSimpleType(elementType)) {
|
||||
if (elementType == null || isSimpleType(elementType)) {
|
||||
collection.add(getPotentiallyConvertedSimpleWrite(element,
|
||||
componentType != null ? componentType.getType() : Object.class));
|
||||
} else if (element instanceof Collection || elementType.isArray()) {
|
||||
|
||||
+6
-2
@@ -23,8 +23,12 @@ import org.springframework.data.mapping.PersistentProperty;
|
||||
*/
|
||||
public class NumberRangePropertyValueConverter extends AbstractRangePropertyValueConverter<Number> {
|
||||
|
||||
public NumberRangePropertyValueConverter(PersistentProperty<?> property) {
|
||||
super(property);
|
||||
/**
|
||||
* @param property the property this convertrer belongs to
|
||||
* @param genericType the generic type of the Range
|
||||
*/
|
||||
public NumberRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
|
||||
super(property, genericType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -34,9 +34,9 @@ public class TemporalRangePropertyValueConverter extends AbstractRangePropertyVa
|
||||
private final List<ElasticsearchDateConverter> dateConverters;
|
||||
|
||||
public TemporalRangePropertyValueConverter(PersistentProperty<?> property,
|
||||
List<ElasticsearchDateConverter> dateConverters) {
|
||||
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {
|
||||
|
||||
super(property);
|
||||
super(property, genericType);
|
||||
|
||||
Assert.notEmpty(dateConverters, "dateConverters must not be empty.");
|
||||
this.dateConverters = dateConverters;
|
||||
|
||||
@@ -332,6 +332,8 @@ public final class MappingParameters {
|
||||
|
||||
if (similarity != Similarity.Default) {
|
||||
objectNode.put(FIELD_PARAM_SIMILARITY, similarity.toString());
|
||||
// similarity must have index explicitly set, otherwise Elasticsearch returns an error
|
||||
objectNode.put(FIELD_PARAM_INDEX, index);
|
||||
}
|
||||
|
||||
if (termVector != TermVector.none) {
|
||||
|
||||
+19
-5
@@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -54,6 +55,7 @@ import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||
import org.springframework.data.mapping.model.Property;
|
||||
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -158,6 +160,18 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
return;
|
||||
}
|
||||
|
||||
Supplier<Class<?>> getGenericType = () -> {
|
||||
TypeInformation<?> typeInformation = getTypeInformation();
|
||||
|
||||
if (typeInformation.isCollectionLike()) {
|
||||
// we have a collection of Range<?>
|
||||
typeInformation = typeInformation.getComponentType();
|
||||
}
|
||||
|
||||
Class<?> genericType = typeInformation.getTypeArguments().get(0).getType();
|
||||
return genericType;
|
||||
};
|
||||
|
||||
switch (field.type()) {
|
||||
case Date:
|
||||
case Date_Nanos: {
|
||||
@@ -187,11 +201,11 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
|
||||
var genericType = getGenericType.get();
|
||||
if (TemporalAccessor.class.isAssignableFrom(genericType)) {
|
||||
propertyValueConverter = new TemporalRangePropertyValueConverter(this, dateConverters);
|
||||
propertyValueConverter = new TemporalRangePropertyValueConverter(this, genericType, dateConverters);
|
||||
} else if (Date.class.isAssignableFrom(genericType)) {
|
||||
propertyValueConverter = new DateRangePropertyValueConverter(this, dateConverters);
|
||||
propertyValueConverter = new DateRangePropertyValueConverter(this, genericType, dateConverters);
|
||||
} else {
|
||||
LOGGER.warn(
|
||||
String.format("Unsupported generic type '{%s' for date range property '%s'.", genericType, getName()));
|
||||
@@ -206,7 +220,7 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
|
||||
var genericType = getGenericType.get();
|
||||
if ((field.type() == FieldType.Integer_Range && !Integer.class.isAssignableFrom(genericType))
|
||||
|| (field.type() == FieldType.Float_Range && !Float.class.isAssignableFrom(genericType))
|
||||
|| (field.type() == FieldType.Long_Range && !Long.class.isAssignableFrom(genericType))
|
||||
@@ -216,7 +230,7 @@ public class SimpleElasticsearchPersistentProperty extends
|
||||
return;
|
||||
}
|
||||
|
||||
propertyValueConverter = new NumberRangePropertyValueConverter(this);
|
||||
propertyValueConverter = new NumberRangePropertyValueConverter(this, genericType);
|
||||
break;
|
||||
}
|
||||
case Ip_Range: {
|
||||
|
||||
@@ -71,7 +71,7 @@ public class BaseQuery implements Query {
|
||||
protected List<RescorerQuery> rescorerQueries = new ArrayList<>();
|
||||
@Nullable protected Boolean requestCache;
|
||||
protected List<IdWithRouting> idsWithRouting = Collections.emptyList();
|
||||
protected final List<RuntimeField> runtimeFields = new ArrayList<>();
|
||||
protected List<RuntimeField> runtimeFields = new ArrayList<>();
|
||||
@Nullable protected PointInTime pointInTime;
|
||||
|
||||
private boolean queryIsUpdatedByConverter = false;
|
||||
@@ -105,6 +105,14 @@ public class BaseQuery implements Query {
|
||||
this.requestCache = builder.getRequestCache();
|
||||
this.idsWithRouting = builder.getIdsWithRouting();
|
||||
this.pointInTime = builder.getPointInTime();
|
||||
this.runtimeFields = builder.getRuntimeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public void setSort(@Nullable Sort sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data Elasticsearch 5.0.3 (2022.0.3)
|
||||
Spring Data Elasticsearch 5.0.11 (2022.0.11)
|
||||
Copyright (c) [2013-2021] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
@@ -19,3 +19,11 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2023 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 co.elastic.clients.elasticsearch.core.search.HitsMetadata;
|
||||
import co.elastic.clients.elasticsearch.core.search.Suggestion;
|
||||
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
|
||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.json.JSONException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Tests for the factory class to create {@link SearchDocumentResponse} instances.
|
||||
*
|
||||
* @author Sébastien Comeau
|
||||
* @since 5.2
|
||||
*/
|
||||
class SearchDocumentResponseBuilderUnitTests {
|
||||
|
||||
private JacksonJsonpMapper jsonpMapper = new JacksonJsonpMapper();
|
||||
|
||||
@Test // #2681
|
||||
void shouldGetPhraseSuggestion() throws JSONException {
|
||||
// arrange
|
||||
final var hitsMetadata = new HitsMetadata.Builder<EntityAsMap>()
|
||||
.total(total -> total
|
||||
.value(0)
|
||||
.relation(TotalHitsRelation.Eq))
|
||||
.hits(new ArrayList<>())
|
||||
.build();
|
||||
|
||||
final var suggestionTest = new Suggestion.Builder<EntityAsMap>()
|
||||
.phrase(phrase -> phrase
|
||||
.text("National")
|
||||
.offset(0)
|
||||
.length(8)
|
||||
.options(option -> option
|
||||
.text("nations")
|
||||
.highlighted("highlighted-nations")
|
||||
.score(0.11480146)
|
||||
.collateMatch(false))
|
||||
.options(option -> option
|
||||
.text("national")
|
||||
.highlighted("highlighted-national")
|
||||
.score(0.08063514)
|
||||
.collateMatch(false)))
|
||||
.build();
|
||||
|
||||
final var sortProperties = ImmutableMap.<String, List<Suggestion<EntityAsMap>>> builder()
|
||||
.put("suggestionTest", ImmutableList.of(suggestionTest))
|
||||
.build();
|
||||
|
||||
// act
|
||||
final var actual = SearchDocumentResponseBuilder.from(hitsMetadata, null, null, null, sortProperties, null,
|
||||
jsonpMapper);
|
||||
|
||||
// assert
|
||||
SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
softly.assertThat(actual).isNotNull();
|
||||
softly.assertThat(actual.getSuggest()).isNotNull();
|
||||
softly.assertThat(actual.getSuggest().getSuggestions()).isNotNull().hasSize(1);
|
||||
|
||||
final var actualSuggestion = actual.getSuggest().getSuggestions().get(0);
|
||||
softly.assertThat(actualSuggestion.getName()).isEqualTo("suggestionTest");
|
||||
softly.assertThat(actualSuggestion.getEntries()).isNotNull().hasSize(1);
|
||||
|
||||
final var actualEntry = actualSuggestion.getEntries().get(0);
|
||||
softly.assertThat(actualEntry).isNotNull();
|
||||
softly.assertThat(actualEntry.getText()).isEqualTo("National");
|
||||
softly.assertThat(actualEntry.getOffset()).isEqualTo(0);
|
||||
softly.assertThat(actualEntry.getLength()).isEqualTo(8);
|
||||
softly.assertThat(actualEntry.getOptions()).isNotNull().hasSize(2);
|
||||
|
||||
final var actualOption1 = actualEntry.getOptions().get(0);
|
||||
softly.assertThat(actualOption1.getText()).isEqualTo("nations");
|
||||
softly.assertThat(actualOption1.getHighlighted()).isEqualTo("highlighted-nations");
|
||||
softly.assertThat(actualOption1.getScore()).isEqualTo(0.11480146);
|
||||
softly.assertThat(actualOption1.getCollateMatch()).isEqualTo(false);
|
||||
|
||||
final var actualOption2 = actualEntry.getOptions().get(1);
|
||||
softly.assertThat(actualOption2.getText()).isEqualTo("national");
|
||||
softly.assertThat(actualOption2.getHighlighted()).isEqualTo("highlighted-national");
|
||||
softly.assertThat(actualOption2.getScore()).isEqualTo(0.08063514);
|
||||
softly.assertThat(actualOption2.getCollateMatch()).isEqualTo(false);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
}
|
||||
+10
-4
@@ -42,6 +42,7 @@ import org.springframework.lang.Nullable;
|
||||
* Testing the querying and parsing of inner_hits.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Jakob Hoeper
|
||||
*/
|
||||
@SpringIntegrationTest
|
||||
public abstract class InnerHitsIntegrationTests {
|
||||
@@ -58,8 +59,9 @@ public abstract class InnerHitsIntegrationTests {
|
||||
indexOps.createWithMapping();
|
||||
|
||||
Inhabitant john = new Inhabitant("John", "Smith");
|
||||
Inhabitant carla = new Inhabitant("Carla", "Miller");
|
||||
House cornerHouse = new House("Round the corner", "7", Arrays.asList(john, carla));
|
||||
Inhabitant carla1 = new Inhabitant("Carla", "Miller");
|
||||
Inhabitant carla2 = new Inhabitant("Carla", "Nguyen");
|
||||
House cornerHouse = new House("Round the corner", "7", Arrays.asList(john, carla1, carla2));
|
||||
City metropole = new City("Metropole", Arrays.asList(cornerHouse));
|
||||
|
||||
Inhabitant jack = new Inhabitant("Jack", "Wayne");
|
||||
@@ -76,7 +78,7 @@ public abstract class InnerHitsIntegrationTests {
|
||||
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*")).delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // #2521
|
||||
void shouldReturnInnerHits() {
|
||||
|
||||
Query query = buildQueryForInnerHits("inner_hit_name", "hou-ses.in-habi-tants", "hou-ses.in-habi-tants.first-name",
|
||||
@@ -91,7 +93,7 @@ public abstract class InnerHitsIntegrationTests {
|
||||
softly.assertThat(searchHit.getInnerHits()).hasSize(1);
|
||||
|
||||
SearchHits<?> innerHits = searchHit.getInnerHits("inner_hit_name");
|
||||
softly.assertThat(innerHits).hasSize(1);
|
||||
softly.assertThat(innerHits).hasSize(2);
|
||||
|
||||
SearchHit<?> innerHit = innerHits.getSearchHit(0);
|
||||
Object content = innerHit.getContent();
|
||||
@@ -106,6 +108,10 @@ public abstract class InnerHitsIntegrationTests {
|
||||
softly.assertThat(nestedMetaData.getChild().getField()).isEqualTo("inhabitants");
|
||||
softly.assertThat(nestedMetaData.getChild().getOffset()).isEqualTo(1);
|
||||
|
||||
innerHit = innerHits.getSearchHit(1);
|
||||
softly.assertThat(((Inhabitant) innerHit.getContent()).getLastName()).isEqualTo("Nguyen");
|
||||
softly.assertThat(innerHit.getNestedMetaData().getChild().getOffset()).isEqualTo(2);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
|
||||
+111
-15
@@ -908,22 +908,109 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
assertEquals(expected, document.toJson(), false);
|
||||
}
|
||||
|
||||
@Test // #2627
|
||||
@DisplayName("should write Map containing collection containing map")
|
||||
void shouldWriteMapContainingCollectionContainingMap() throws JSONException {
|
||||
|
||||
class EntityWithMapCollectionMap {
|
||||
Map<String, Object> map;
|
||||
}
|
||||
class InnerEntity {
|
||||
String prop1;
|
||||
|
||||
String prop2;
|
||||
|
||||
public InnerEntity() {}
|
||||
|
||||
public InnerEntity(String prop1, String prop2) {
|
||||
this.prop1 = prop1;
|
||||
this.prop2 = prop2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var entity = new EntityWithMapCollectionMap();
|
||||
entity.map = Collections.singletonMap("collection",
|
||||
Collections.singletonList(Collections.singletonMap("destination", new InnerEntity("prop1", "prop2"))));
|
||||
|
||||
var expected = """
|
||||
{
|
||||
"_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$1EntityWithMapCollectionMap",
|
||||
"map": {
|
||||
"collection": [
|
||||
{
|
||||
"destination": {
|
||||
"_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$1InnerEntity",
|
||||
"prop1": "prop1",
|
||||
"prop2": "prop2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
Document document = Document.create();
|
||||
|
||||
mappingElasticsearchConverter.write(entity, document);
|
||||
|
||||
assertEquals(expected, document.toJson(), false);
|
||||
}
|
||||
|
||||
@Nested
|
||||
class RangeTests {
|
||||
|
||||
static final String JSON = "{"
|
||||
+ "\"_class\":\"org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$RangeTests$RangeEntity\","
|
||||
+ "\"integerRange\":{\"gt\":\"1\",\"lt\":\"10\"}," //
|
||||
+ "\"floatRange\":{\"gte\":\"1.2\",\"lte\":\"2.5\"}," //
|
||||
+ "\"longRange\":{\"gt\":\"2\",\"lte\":\"5\"}," //
|
||||
+ "\"doubleRange\":{\"gte\":\"3.2\",\"lt\":\"7.4\"}," //
|
||||
+ "\"dateRange\":{\"gte\":\"1970-01-01T00:00:00.000Z\",\"lte\":\"1970-01-01T01:00:00.000Z\"}," //
|
||||
+ "\"localDateRange\":{\"gte\":\"2021-07-06\"}," //
|
||||
+ "\"localTimeRange\":{\"gte\":\"00:30:00.000\",\"lt\":\"02:30:00.000\"}," //
|
||||
+ "\"localDateTimeRange\":{\"gt\":\"2021-01-01T00:30:00.000\",\"lt\":\"2021-01-01T02:30:00.000\"}," //
|
||||
+ "\"offsetTimeRange\":{\"gte\":\"00:30:00.000+02:00\",\"lt\":\"02:30:00.000+02:00\"}," //
|
||||
+ "\"zonedDateTimeRange\":{\"gte\":\"2021-01-01T00:30:00.000+02:00\",\"lte\":\"2021-01-01T00:30:00.000+02:00\"}," //
|
||||
+ "\"nullRange\":null}";
|
||||
static final String JSON = """
|
||||
{
|
||||
"_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$RangeTests$RangeEntity",
|
||||
"integerRange": {
|
||||
"gt": "1",
|
||||
"lt": "10"
|
||||
},
|
||||
"floatRange": {
|
||||
"gte": "1.2",
|
||||
"lte": "2.5"
|
||||
},
|
||||
"longRange": {
|
||||
"gt": "2",
|
||||
"lte": "5"
|
||||
},
|
||||
"doubleRange": {
|
||||
"gte": "3.2",
|
||||
"lt": "7.4"
|
||||
},
|
||||
"dateRange": {
|
||||
"gte": "1970-01-01T00:00:00.000Z",
|
||||
"lte": "1970-01-01T01:00:00.000Z"
|
||||
},
|
||||
"localDateRange": {
|
||||
"gte": "2021-07-06"
|
||||
},
|
||||
"localTimeRange": {
|
||||
"gte": "00:30:00.000",
|
||||
"lt": "02:30:00.000"
|
||||
},
|
||||
"localDateTimeRange": {
|
||||
"gt": "2021-01-01T00:30:00.000",
|
||||
"lt": "2021-01-01T02:30:00.000"
|
||||
},
|
||||
"offsetTimeRange": {
|
||||
"gte": "00:30:00.000+02:00",
|
||||
"lt": "02:30:00.000+02:00"
|
||||
},
|
||||
"zonedDateTimeRange": {
|
||||
"gte": "2021-01-01T00:30:00.000+02:00",
|
||||
"lte": "2021-01-01T00:30:00.000+02:00"
|
||||
},
|
||||
"nullRange": null,
|
||||
"integerRangeList": [
|
||||
{
|
||||
"gte": "2",
|
||||
"lte": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
@Test
|
||||
public void shouldReadRanges() throws JSONException {
|
||||
@@ -954,6 +1041,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
assertThat(e.getZonedDateTimeRange()).isEqualTo(
|
||||
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
|
||||
assertThat(e.getNullRange()).isNull();
|
||||
assertThat(e.getIntegerRangeList()).containsExactly(Range.closed(2, 5));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -977,8 +1065,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
entity.setZonedDateTimeRange(
|
||||
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
|
||||
entity.setNullRange(null);
|
||||
|
||||
// when
|
||||
entity.setIntegerRangeList(List.of(Range.closed(2, 5)));
|
||||
Document document = mappingElasticsearchConverter.mapObject(entity);
|
||||
|
||||
// then
|
||||
@@ -1003,6 +1090,8 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Field(type = FieldType.Date_Range) private Range<ZonedDateTime> zonedDateTimeRange;
|
||||
@Field(type = FieldType.Date_Range, storeNullValue = true) private Range<ZonedDateTime> nullRange;
|
||||
|
||||
@Field(type = FieldType.Integer_Range) private List<Range<Integer>> integerRangeList;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -1099,6 +1188,13 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
this.nullRange = nullRange;
|
||||
}
|
||||
|
||||
public List<Range<Integer>> getIntegerRangeList() {
|
||||
return integerRangeList;
|
||||
}
|
||||
|
||||
public void setIntegerRangeList(List<Range<Integer>> integerRangeList) {
|
||||
this.integerRangeList = integerRangeList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -63,13 +63,14 @@ public class PropertyValueConvertersUnitTests {
|
||||
|
||||
converters.add(new DatePropertyValueConverter(persistentProperty,
|
||||
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||
Class<?> genericType = Object.class;
|
||||
converters.add(new DateRangePropertyValueConverter(persistentProperty,
|
||||
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||
converters.add(new NumberRangePropertyValueConverter(persistentProperty));
|
||||
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||
converters.add(new NumberRangePropertyValueConverter(persistentProperty, genericType));
|
||||
converters.add(new TemporalPropertyValueConverter(persistentProperty,
|
||||
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||
converters.add(new TemporalRangePropertyValueConverter(persistentProperty,
|
||||
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||
|
||||
return converters.stream().map(propertyValueConverter -> arguments(
|
||||
Named.of(propertyValueConverter.getClass().getSimpleName(), propertyValueConverter)));
|
||||
|
||||
+2
-10
@@ -37,22 +37,14 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIf;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.NewElasticsearchClientDevelopment;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Dynamic;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.InnerField;
|
||||
import org.springframework.data.elasticsearch.annotations.Mapping;
|
||||
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
import org.springframework.data.elasticsearch.annotations.TermVector;
|
||||
import org.springframework.data.elasticsearch.annotations.*;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.IndexOperations;
|
||||
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
|
||||
|
||||
+81
-14
@@ -62,7 +62,7 @@ public abstract class SearchAfterIntegrationTests {
|
||||
@Test
|
||||
@Order(java.lang.Integer.MAX_VALUE)
|
||||
void cleanup() {
|
||||
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*")).delete();
|
||||
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + '*')).delete();
|
||||
}
|
||||
|
||||
@Test // #1143
|
||||
@@ -85,11 +85,11 @@ public abstract class SearchAfterIntegrationTests {
|
||||
query.setSearchAfter(searchAfter);
|
||||
SearchHits<Entity> searchHits = operations.search(query, Entity.class);
|
||||
|
||||
if (searchHits.getSearchHits().size() == 0) {
|
||||
if (searchHits.getSearchHits().isEmpty()) {
|
||||
break;
|
||||
}
|
||||
foundEntities.addAll(searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList()));
|
||||
searchAfter = searchHits.getSearchHit((int) (searchHits.getSearchHits().size() - 1)).getSortValues();
|
||||
foundEntities.addAll(searchHits.stream().map(SearchHit::getContent).toList());
|
||||
searchAfter = searchHits.getSearchHit(searchHits.getSearchHits().size() - 1).getSortValues();
|
||||
|
||||
if (++loop > 10) {
|
||||
fail("loop not terminating");
|
||||
@@ -99,16 +99,69 @@ public abstract class SearchAfterIntegrationTests {
|
||||
assertThat(foundEntities).containsExactlyElementsOf(entities);
|
||||
}
|
||||
|
||||
@Test // #2678
|
||||
@DisplayName("should be able to handle different search after type values including null")
|
||||
void shouldBeAbleToHandleDifferentSearchAfterTypeValuesIncludingNull() {
|
||||
|
||||
List<Entity> entities = IntStream.rangeClosed(1, 10)
|
||||
.mapToObj(i -> {
|
||||
var message = (i % 2 == 0) ? null : "message " + i;
|
||||
var value = (i % 3 == 0) ? null : (long) i;
|
||||
return new Entity((long) i, message, value);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
operations.save(entities);
|
||||
|
||||
Query query = Query.findAll();
|
||||
query.setPageable(PageRequest.of(0, 3));
|
||||
query.addSort(Sort.by(Sort.Direction.ASC, "id"));
|
||||
query.addSort(Sort.by(Sort.Direction.ASC, "keyword"));
|
||||
query.addSort(Sort.by(Sort.Direction.ASC, "value"));
|
||||
|
||||
List<Object> searchAfter = null;
|
||||
List<Entity> foundEntities = new ArrayList<>();
|
||||
|
||||
int loop = 0;
|
||||
do {
|
||||
query.setSearchAfter(searchAfter);
|
||||
SearchHits<Entity> searchHits = operations.search(query, Entity.class);
|
||||
|
||||
if (searchHits.getSearchHits().isEmpty()) {
|
||||
break;
|
||||
}
|
||||
foundEntities.addAll(searchHits.stream().map(SearchHit::getContent).toList());
|
||||
searchAfter = searchHits.getSearchHit(searchHits.getSearchHits().size() - 1).getSortValues();
|
||||
|
||||
if (++loop > 10) {
|
||||
fail("loop not terminating");
|
||||
}
|
||||
} while (true);
|
||||
|
||||
assertThat(foundEntities).containsExactlyElementsOf(entities);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||
private static class Entity {
|
||||
@Nullable
|
||||
@Id private Long id;
|
||||
@Nullable
|
||||
@Field(type = FieldType.Text) private String message;
|
||||
@Field(type = FieldType.Keyword) private String keyword;
|
||||
|
||||
public Entity(@Nullable Long id, @Nullable String message) {
|
||||
@Nullable
|
||||
@Field(type = FieldType.Long) private Long value;
|
||||
|
||||
public Entity() {}
|
||||
|
||||
public Entity(@Nullable Long id, @Nullable String keyword) {
|
||||
this.id = id;
|
||||
this.message = message;
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
public Entity(@Nullable Long id, @Nullable String keyword, @Nullable Long value) {
|
||||
this.id = id;
|
||||
this.keyword = keyword;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -121,30 +174,44 @@ public abstract class SearchAfterIntegrationTests {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMessage() {
|
||||
return message;
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public void setMessage(@Nullable String message) {
|
||||
this.message = message;
|
||||
public void setKeyword(@Nullable String keyword) {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(@Nullable Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof Entity entity))
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
Entity entity = (Entity) o;
|
||||
|
||||
if (!Objects.equals(id, entity.id))
|
||||
return false;
|
||||
return Objects.equals(message, entity.message);
|
||||
if (!Objects.equals(keyword, entity.keyword))
|
||||
return false;
|
||||
return Objects.equals(value, entity.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = id != null ? id.hashCode() : 0;
|
||||
result = 31 * result + (message != null ? message.hashCode() : 0);
|
||||
result = 31 * result + (keyword != null ? keyword.hashCode() : 0);
|
||||
result = 31 * result + (value != null ? value.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+35
@@ -1590,6 +1590,41 @@ public abstract class CustomMethodRepositoryIntegrationTests implements NewElast
|
||||
assertThat(searchHits.getSearchHit(2).getId()).isEqualTo("oslo");
|
||||
}
|
||||
|
||||
@Test // #2601
|
||||
void shouldUseGeoSortReverseParameter() {
|
||||
GeoPoint munich = new GeoPoint(48.137154, 11.5761247);
|
||||
GeoPoint berlin = new GeoPoint(52.520008, 13.404954);
|
||||
GeoPoint vienna = new GeoPoint(48.20849, 16.37208);
|
||||
GeoPoint oslo = new GeoPoint(59.9127, 10.7461);
|
||||
|
||||
List<SampleEntity> entities = new ArrayList<>();
|
||||
|
||||
SampleEntity entity1 = new SampleEntity();
|
||||
entity1.setId("berlin");
|
||||
entity1.setLocation(berlin);
|
||||
entities.add(entity1);
|
||||
|
||||
SampleEntity entity2 = new SampleEntity();
|
||||
entity2.setId("vienna");
|
||||
entity2.setLocation(vienna);
|
||||
entities.add(entity2);
|
||||
|
||||
SampleEntity entity3 = new SampleEntity();
|
||||
entity3.setId("oslo");
|
||||
entity3.setLocation(oslo);
|
||||
entities.add(entity3);
|
||||
|
||||
repository.saveAll(entities);
|
||||
|
||||
SearchHits<SampleEntity> searchHits = repository
|
||||
.searchBy(Sort.by(new GeoDistanceOrder("location", munich).with(Sort.Direction.DESC)));
|
||||
|
||||
assertThat(searchHits.getTotalHits()).isEqualTo(3);
|
||||
assertThat(searchHits.getSearchHit(0).getId()).isEqualTo("oslo");
|
||||
assertThat(searchHits.getSearchHit(1).getId()).isEqualTo("berlin");
|
||||
assertThat(searchHits.getSearchHit(2).getId()).isEqualTo("vienna");
|
||||
}
|
||||
|
||||
@Test // DATAES-749
|
||||
void shouldReturnSearchPage() {
|
||||
List<SampleEntity> entities = createSampleEntities("abc", 20);
|
||||
|
||||
Reference in New Issue
Block a user