Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf3248b536 | |||
| c59bb0b434 | |||
| d93d1e0738 | |||
| aebdc8f86b | |||
| 2be27593d6 | |||
| aa22d8239d | |||
| 6746bc5278 | |||
| a6cb959605 | |||
| e04905a1a7 | |||
| 834b10f578 | |||
| 823cfa919a | |||
| ab29ae4219 | |||
| 62fb89208a | |||
| e8c3badc56 | |||
| 187c9bbd5d | |||
| e1a5811406 | |||
| b643669d36 | |||
| f66af53480 | |||
| 14099970bb | |||
| 0ab253422f | |||
| 0d2a6b98e8 | |||
| 30602496bd | |||
| 95762b4fde | |||
| 0771e90031 | |||
| 6729330500 | |||
| 8796292611 | |||
| f3f9ca4002 | |||
| 083a38ed57 | |||
| 4f3aa52958 | |||
| 3256a2bfe0 | |||
| 95401a5bd7 | |||
| 12cd64cfc8 | |||
| 7e557317d1 | |||
| c9846ab8ad |
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
#Mon Oct 11 14:30:32 CEST 2021
|
#Tue Feb 22 13:56:16 CET 2022
|
||||||
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.8.3/apache-maven-3.8.3-bin.zip
|
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
|
||||||
|
|||||||
Vendored
+27
-49
@@ -1,9 +1,15 @@
|
|||||||
|
def p = [:]
|
||||||
|
node {
|
||||||
|
checkout scm
|
||||||
|
p = readProperties interpolate: true, file: 'ci/pipeline.properties'
|
||||||
|
}
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent none
|
agent none
|
||||||
|
|
||||||
triggers {
|
triggers {
|
||||||
pollSCM 'H/10 * * * *'
|
pollSCM 'H/10 * * * *'
|
||||||
upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS)
|
upstream(upstreamProjects: "spring-data-commons/2.6.x", threshold: hudson.model.Result.SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
options {
|
options {
|
||||||
@@ -12,7 +18,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage("test: baseline (jdk8)") {
|
stage("test: baseline (main)") {
|
||||||
when {
|
when {
|
||||||
anyOf {
|
anyOf {
|
||||||
branch 'main'
|
branch 'main'
|
||||||
@@ -25,14 +31,14 @@ pipeline {
|
|||||||
options { timeout(time: 30, unit: 'MINUTES') }
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
DOCKER_HUB = credentials('hub.docker.com-springbuildmaster')
|
DOCKER_HUB = credentials("${p['docker.credentials']}")
|
||||||
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||||
docker.image('adoptopenjdk/openjdk8:latest').inside('-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home') {
|
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 "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
|
||||||
sh 'PROFILE=none ci/verify.sh'
|
sh 'PROFILE=none ci/verify.sh'
|
||||||
sh "ci/clean.sh"
|
sh "ci/clean.sh"
|
||||||
@@ -50,23 +56,23 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
parallel {
|
parallel {
|
||||||
stage("test: baseline (jdk11)") {
|
stage("test: baseline (next)") {
|
||||||
agent {
|
agent {
|
||||||
label 'data'
|
label 'data'
|
||||||
}
|
}
|
||||||
options { timeout(time: 30, unit: 'MINUTES') }
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
DOCKER_HUB = credentials('hub.docker.com-springbuildmaster')
|
DOCKER_HUB = credentials("${p['docker.credentials']}")
|
||||||
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||||
docker.image('adoptopenjdk/openjdk11:latest').inside('-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home') {
|
docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) {
|
||||||
sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
|
sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
|
||||||
sh 'PROFILE=java11 ci/verify.sh'
|
sh 'PROFILE=none ci/verify.sh'
|
||||||
sh "ci/clean.sh"
|
sh "ci/clean.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,23 +80,23 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage("test: baseline (jdk17)") {
|
stage("test: baseline (LTS)") {
|
||||||
agent {
|
agent {
|
||||||
label 'data'
|
label 'data'
|
||||||
}
|
}
|
||||||
options { timeout(time: 30, unit: 'MINUTES') }
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
DOCKER_HUB = credentials('hub.docker.com-springbuildmaster')
|
DOCKER_HUB = credentials("${p['docker.credentials']}")
|
||||||
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||||
docker.image('openjdk:17-bullseye').inside('-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home') {
|
docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.docker']) {
|
||||||
sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
|
sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
|
||||||
sh 'PROFILE=java11 ci/verify.sh'
|
sh 'PROFILE=none ci/verify.sh'
|
||||||
sh "ci/clean.sh"
|
sh "ci/clean.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,13 +119,13 @@ pipeline {
|
|||||||
options { timeout(time: 20, unit: 'MINUTES') }
|
options { timeout(time: 20, unit: 'MINUTES') }
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||||
docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
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 ' +
|
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.server=https://repo.spring.io ' +
|
||||||
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||||
@@ -133,34 +139,6 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Publish documentation') {
|
|
||||||
when {
|
|
||||||
branch 'main'
|
|
||||||
}
|
|
||||||
agent {
|
|
||||||
label 'data'
|
|
||||||
}
|
|
||||||
options { timeout(time: 20, unit: 'MINUTES') }
|
|
||||||
|
|
||||||
environment {
|
|
||||||
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
|
||||||
docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
|
||||||
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,distribute -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.distribution-repository=temp-private-local " +
|
|
||||||
'-Dmaven.test.skip=true clean deploy -U -B'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Java versions
|
||||||
|
java.main.tag=8u322-b06-jdk
|
||||||
|
java.next.tag=11.0.14.1_1-jdk
|
||||||
|
java.lts.tag=17.0.2_8-jdk
|
||||||
|
|
||||||
|
# Docker container images - standard
|
||||||
|
docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag}
|
||||||
|
docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag}
|
||||||
|
docker.java.lts.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.lts.tag}
|
||||||
|
|
||||||
|
# Supported versions of MongoDB
|
||||||
|
docker.mongodb.4.0.version=4.0.28
|
||||||
|
docker.mongodb.4.4.version=4.4.12
|
||||||
|
docker.mongodb.5.0.version=5.0.6
|
||||||
|
|
||||||
|
# Supported versions of Redis
|
||||||
|
docker.redis.6.version=6.2.6
|
||||||
|
|
||||||
|
# Supported versions of Cassandra
|
||||||
|
docker.cassandra.3.version=3.11.12
|
||||||
|
|
||||||
|
# Docker environment settings
|
||||||
|
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
|
||||||
|
docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home
|
||||||
|
|
||||||
|
# Credentials
|
||||||
|
docker.registry=
|
||||||
|
docker.credentials=hub.docker.com-springbuildmaster
|
||||||
|
artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c
|
||||||
@@ -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>4.3.0</version>
|
<version>4.3.3</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data.build</groupId>
|
<groupId>org.springframework.data.build</groupId>
|
||||||
<artifactId>spring-data-parent</artifactId>
|
<artifactId>spring-data-parent</artifactId>
|
||||||
<version>2.6.0</version>
|
<version>2.6.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>Spring Data Elasticsearch</name>
|
<name>Spring Data Elasticsearch</name>
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<elasticsearch>7.15.2</elasticsearch>
|
<elasticsearch>7.15.2</elasticsearch>
|
||||||
<log4j>2.14.1</log4j>
|
<log4j>2.17.0</log4j>
|
||||||
<netty>4.1.65.Final</netty>
|
<netty>4.1.65.Final</netty>
|
||||||
<springdata.commons>2.6.0</springdata.commons>
|
<springdata.commons>2.6.3</springdata.commons>
|
||||||
<testcontainers>1.15.3</testcontainers>
|
<testcontainers>1.15.3</testcontainers>
|
||||||
<blockhound-junit>1.0.6.RELEASE</blockhound-junit>
|
<blockhound-junit>1.0.6.RELEASE</blockhound-junit>
|
||||||
<java-module-name>spring.data.elasticsearch</java-module-name>
|
<java-module-name>spring.data.elasticsearch</java-module-name>
|
||||||
@@ -145,6 +145,12 @@
|
|||||||
<groupId>org.elasticsearch.client</groupId>
|
<groupId>org.elasticsearch.client</groupId>
|
||||||
<artifactId>transport</artifactId>
|
<artifactId>transport</artifactId>
|
||||||
<version>${elasticsearch}</version>
|
<version>${elasticsearch}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -152,6 +158,12 @@
|
|||||||
<groupId>org.elasticsearch.plugin</groupId>
|
<groupId>org.elasticsearch.plugin</groupId>
|
||||||
<artifactId>transport-netty4-client</artifactId>
|
<artifactId>transport-netty4-client</artifactId>
|
||||||
<version>${elasticsearch}</version>
|
<version>${elasticsearch}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -461,7 +473,9 @@
|
|||||||
</module>
|
</module>
|
||||||
</checkstyleRules>
|
</checkstyleRules>
|
||||||
<includes>**/*</includes>
|
<includes>**/*</includes>
|
||||||
<excludes>.git/**/*,target/**/*,**/target/**/*,.idea/**/*,**/spring.schemas,**/*.svg,mvnw,mvnw.cmd,**/*.policy</excludes>
|
<excludes>
|
||||||
|
.git/**/*,target/**/*,**/target/**/*,.idea/**/*,**/spring.schemas,**/*.svg,mvnw,mvnw.cmd,**/*.policy
|
||||||
|
</excludes>
|
||||||
<sourceDirectories>./</sourceDirectories>
|
<sourceDirectories>./</sourceDirectories>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -199,6 +199,29 @@ Default is 5 sec.
|
|||||||
IMPORTANT: Adding a Header supplier as shown in above example allows to inject headers that may change over the time, like authentication JWT tokens.
|
IMPORTANT: Adding a Header supplier as shown in above example allows to inject headers that may change over the time, like authentication JWT tokens.
|
||||||
If this is used in the reactive setup, the supplier function *must not* block!
|
If this is used in the reactive setup, the supplier function *must not* block!
|
||||||
|
|
||||||
|
=== Elasticsearch 7 compatibility headers
|
||||||
|
|
||||||
|
When using Spring Data Elasticsearch 4 - which uses the Elasticsearch 7 client libraries - and accessing an Elasticsearch cluster that is running on version 8, it is necessary to set the compatibility headers
|
||||||
|
https://www.elastic.co/guide/en/elasticsearch/reference/8.0/rest-api-compatibility.html[see Elasticserach documentation].
|
||||||
|
This should be done using a header supplier like shown above:
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder();
|
||||||
|
configurationBuilder //
|
||||||
|
// ...
|
||||||
|
.withHeaders(() -> {
|
||||||
|
HttpHeaders defaultCompatibilityHeaders = new HttpHeaders();
|
||||||
|
defaultCompatibilityHeaders.add("Accept",
|
||||||
|
"application/vnd.elasticsearch+json;compatible-with=7");
|
||||||
|
defaultCompatibilityHeaders.add("Content-Type",
|
||||||
|
"application/vnd.elasticsearch+json;compatible-with=7");
|
||||||
|
return defaultCompatibilityHeaders;
|
||||||
|
});
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
[[elasticsearch.clients.logging]]
|
[[elasticsearch.clients.logging]]
|
||||||
== Client Logging
|
== Client Logging
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -46,6 +46,16 @@ public @interface CompletionContext {
|
|||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
enum ContextMappingType {
|
enum ContextMappingType {
|
||||||
CATEGORY, GEO
|
CATEGORY("category"), GEO("geo");
|
||||||
|
|
||||||
|
private final String mappedName;
|
||||||
|
|
||||||
|
ContextMappingType(String mappedName) {
|
||||||
|
this.mappedName = mappedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMappedName() {
|
||||||
|
return mappedName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public @interface Document {
|
|||||||
* Name of the Elasticsearch index.
|
* Name of the Elasticsearch index.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Lowercase only</li>
|
* <li>Lowercase only</li>
|
||||||
* <li>Cannot include \, /, *, ?, ", <, >, |, ` ` (space character), ,, #</li>
|
* <li>Cannot include \, /, *, ?, ", >, <, |, ` ` (space character), ,, #</li>
|
||||||
* <li>Cannot start with -, _, +</li>
|
* <li>Cannot start with -, _, +</li>
|
||||||
* <li>Cannot be . or ..</li>
|
* <li>Cannot be . or ..</li>
|
||||||
* <li>Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit
|
* <li>Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit
|
||||||
|
|||||||
@@ -25,26 +25,36 @@ public enum Dynamic {
|
|||||||
/**
|
/**
|
||||||
* New fields are added to the mapping.
|
* New fields are added to the mapping.
|
||||||
*/
|
*/
|
||||||
TRUE,
|
TRUE("true"),
|
||||||
/**
|
/**
|
||||||
* New fields are added to the mapping as
|
* New fields are added to the mapping as
|
||||||
* <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html">runtime fields</a>. These
|
* <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html">runtime fields</a>. These
|
||||||
* fields are not indexed, and are loaded from {@code _source} at query time.
|
* fields are not indexed, and are loaded from {@code _source} at query time.
|
||||||
*/
|
*/
|
||||||
RUNTIME,
|
RUNTIME("runtime"),
|
||||||
/**
|
/**
|
||||||
* New fields are ignored. These fields will not be indexed or searchable, but will still appear in the
|
* New fields are ignored. These fields will not be indexed or searchable, but will still appear in the
|
||||||
* {@code _source} field of returned hits. These fields will not be added to the mapping, and new fields must be added
|
* {@code _source} field of returned hits. These fields will not be added to the mapping, and new fields must be added
|
||||||
* explicitly.
|
* explicitly.
|
||||||
*/
|
*/
|
||||||
FALSE,
|
FALSE("false"),
|
||||||
/**
|
/**
|
||||||
* If new fields are detected, an exception is thrown and the document is rejected. New fields must be explicitly
|
* If new fields are detected, an exception is thrown and the document is rejected. New fields must be explicitly
|
||||||
* added to the mapping.
|
* added to the mapping.
|
||||||
*/
|
*/
|
||||||
STRICT,
|
STRICT("strict"),
|
||||||
/**
|
/**
|
||||||
* Inherit the dynamic setting from their parent object or from the mapping type.
|
* Inherit the dynamic setting from their parent object or from the mapping type.
|
||||||
*/
|
*/
|
||||||
INHERIT
|
INHERIT("nherit");
|
||||||
|
|
||||||
|
private final String mappedName;
|
||||||
|
|
||||||
|
Dynamic(String mappedName) {
|
||||||
|
this.mappedName = mappedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMappedName() {
|
||||||
|
return mappedName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -25,5 +25,15 @@ package org.springframework.data.elasticsearch.annotations;
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public enum DynamicMappingValue {
|
public enum DynamicMappingValue {
|
||||||
True, False, Strict
|
True("true"), False("false"), Strict("strict");
|
||||||
|
|
||||||
|
private final String mappedName;
|
||||||
|
|
||||||
|
DynamicMappingValue(String mappedName) {
|
||||||
|
this.mappedName = mappedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMappedName() {
|
||||||
|
return mappedName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,40 +26,51 @@ package org.springframework.data.elasticsearch.annotations;
|
|||||||
* @author Morgan Lutz
|
* @author Morgan Lutz
|
||||||
*/
|
*/
|
||||||
public enum FieldType {
|
public enum FieldType {
|
||||||
Auto, //
|
Auto("auto"), //
|
||||||
Text, //
|
Text("text"), //
|
||||||
Keyword, //
|
Keyword("keyword"), //
|
||||||
Long, //
|
Long("long"), //
|
||||||
Integer, //
|
Integer("integer"), //
|
||||||
Short, //
|
Short("short"), //
|
||||||
Byte, //
|
Byte("byte"), //
|
||||||
Double, //
|
Double("double"), //
|
||||||
Float, //
|
Float("float"), //
|
||||||
Half_Float, //
|
Half_Float("half_float"), //
|
||||||
Scaled_Float, //
|
Scaled_Float("scaled_float"), //
|
||||||
Date, //
|
Date("date"), //
|
||||||
Date_Nanos, //
|
Date_Nanos("date_nanos"), //
|
||||||
Boolean, //
|
Boolean("boolean"), //
|
||||||
Binary, //
|
Binary("binary"), //
|
||||||
Integer_Range, //
|
Integer_Range("integer_range"), //
|
||||||
Float_Range, //
|
Float_Range("float_range"), //
|
||||||
Long_Range, //
|
Long_Range("long_range"), //
|
||||||
Double_Range, //
|
Double_Range("double_range"), //
|
||||||
Date_Range, //
|
Date_Range("date_range"), //
|
||||||
Ip_Range, //
|
Ip_Range("ip_range"), //
|
||||||
Object, //
|
Object("object"), //
|
||||||
Nested, //
|
Nested("nested"), //
|
||||||
Ip, //
|
Ip("ip"), //
|
||||||
TokenCount, //
|
TokenCount("token_count"), //
|
||||||
Percolator, //
|
Percolator("percolator"), //
|
||||||
Flattened, //
|
Flattened("flattened"), //
|
||||||
Search_As_You_Type, //
|
Search_As_You_Type("search_as_you_type"), //
|
||||||
/** @since 4.1 */
|
/** @since 4.1 */
|
||||||
Rank_Feature, //
|
Rank_Feature("rank_feature"), //
|
||||||
/** @since 4.1 */
|
/** @since 4.1 */
|
||||||
Rank_Features, //
|
Rank_Features("rank_features"), //
|
||||||
/** since 4.2 */
|
/** since 4.2 */
|
||||||
Wildcard, //
|
Wildcard("wildcard"), //
|
||||||
/** @since 4.2 */
|
/** @since 4.2 */
|
||||||
Dense_Vector //
|
Dense_Vector("dense_vector") //
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String mappedName;
|
||||||
|
|
||||||
|
FieldType(String mappedName) {
|
||||||
|
this.mappedName = mappedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMappedName() {
|
||||||
|
return mappedName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -20,6 +20,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -109,7 +110,8 @@ public abstract class AbstractElasticsearchRestTransportTemplate extends Abstrac
|
|||||||
List<SearchHits<T>> res = new ArrayList<>(queries.size());
|
List<SearchHits<T>> res = new ArrayList<>(queries.size());
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for (Query query : queries) {
|
for (Query query : queries) {
|
||||||
res.add(callback.doWith(SearchDocumentResponse.from(items[c++].getResponse(), documentCallback::doWith)));
|
res.add(
|
||||||
|
callback.doWith(SearchDocumentResponse.from(items[c++].getResponse(), getEntityCreator(documentCallback))));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -142,7 +144,7 @@ public abstract class AbstractElasticsearchRestTransportTemplate extends Abstrac
|
|||||||
index);
|
index);
|
||||||
|
|
||||||
SearchResponse response = items[c++].getResponse();
|
SearchResponse response = items[c++].getResponse();
|
||||||
res.add(callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith)));
|
res.add(callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback))));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -175,7 +177,7 @@ public abstract class AbstractElasticsearchRestTransportTemplate extends Abstrac
|
|||||||
index);
|
index);
|
||||||
|
|
||||||
SearchResponse response = items[c++].getResponse();
|
SearchResponse response = items[c++].getResponse();
|
||||||
res.add(callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith)));
|
res.add(callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback))));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -215,5 +217,9 @@ public abstract class AbstractElasticsearchRestTransportTemplate extends Abstrac
|
|||||||
return suggest(suggestion, getIndexCoordinatesFor(clazz));
|
return suggest(suggestion, getIndexCoordinatesFor(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected <T> SearchDocumentResponse.EntityCreator<T> getEntityCreator(ReadDocumentCallback<T> documentCallback) {
|
||||||
|
return searchDocument -> CompletableFuture.completedFuture(documentCallback.doWith(searchDocument));
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -64,9 +64,9 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (elasticsearchException instanceof ElasticsearchStatusException) {
|
if (elasticsearchException instanceof ElasticsearchStatusException) {
|
||||||
ElasticsearchStatusException restStatusException = (ElasticsearchStatusException) elasticsearchException;
|
ElasticsearchStatusException elasticsearchStatusException = (ElasticsearchStatusException) elasticsearchException;
|
||||||
return new RestStatusException(restStatusException.status().getStatus(), restStatusException.getMessage(),
|
return new RestStatusException(elasticsearchStatusException.status().getStatus(),
|
||||||
restStatusException.getCause());
|
elasticsearchStatusException.getMessage(), elasticsearchStatusException);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UncategorizedElasticsearchException(ex.getMessage(), ex);
|
return new UncategorizedElasticsearchException(ex.getMessage(), ex);
|
||||||
|
|||||||
+5
-5
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013-2021 the original author or authors.
|
* Copyright 2013-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -319,7 +319,7 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchRestTranspor
|
|||||||
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
||||||
SearchDocumentResponseCallback<SearchHits<T>> callback = new ReadSearchDocumentResponseCallback<>(clazz, index);
|
SearchDocumentResponseCallback<SearchHits<T>> callback = new ReadSearchDocumentResponseCallback<>(clazz, index);
|
||||||
|
|
||||||
return callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith));
|
return callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -336,7 +336,7 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchRestTranspor
|
|||||||
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
||||||
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
||||||
index);
|
index);
|
||||||
return callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith));
|
return callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -351,7 +351,7 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchRestTranspor
|
|||||||
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
||||||
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
||||||
index);
|
index);
|
||||||
return callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith));
|
return callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -378,8 +378,8 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchRestTranspor
|
|||||||
Assert.isTrue(items.length == request.requests().size(), "Response should has same length with queries");
|
Assert.isTrue(items.length == request.requests().size(), "Response should has same length with queries");
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
// endregion
|
|
||||||
|
|
||||||
|
// endregion
|
||||||
// region ClientCallback
|
// region ClientCallback
|
||||||
/**
|
/**
|
||||||
* Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on
|
* Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on
|
||||||
|
|||||||
+3
-3
@@ -354,7 +354,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchRestTransportTem
|
|||||||
|
|
||||||
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
||||||
SearchDocumentResponseCallback<SearchHits<T>> callback = new ReadSearchDocumentResponseCallback<>(clazz, index);
|
SearchDocumentResponseCallback<SearchHits<T>> callback = new ReadSearchDocumentResponseCallback<>(clazz, index);
|
||||||
return callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith));
|
return callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -372,7 +372,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchRestTransportTem
|
|||||||
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
||||||
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
||||||
index);
|
index);
|
||||||
return callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith));
|
return callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -389,7 +389,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchRestTransportTem
|
|||||||
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<T>(elasticsearchConverter, clazz, index);
|
||||||
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
|
||||||
index);
|
index);
|
||||||
return callback.doWith(SearchDocumentResponse.from(response, documentCallback::doWith));
|
return callback.doWith(SearchDocumentResponse.from(response, getEntityCreator(documentCallback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+11
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018-2021 the original author or authors.
|
* Copyright 2018-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,7 +23,6 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
@@ -771,15 +770,18 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<SearchDocumentResponse> doFindForResponse(Query query, Class<?> clazz, IndexCoordinates index) {
|
private <T> Mono<SearchDocumentResponse> doFindForResponse(Query query, Class<?> clazz, IndexCoordinates index) {
|
||||||
|
|
||||||
return Mono.defer(() -> {
|
return Mono.defer(() -> {
|
||||||
SearchRequest request = requestFactory.searchRequest(query, clazz, index);
|
SearchRequest request = requestFactory.searchRequest(query, clazz, index);
|
||||||
request = prepareSearchRequest(request, false);
|
request = prepareSearchRequest(request, false);
|
||||||
|
|
||||||
SearchDocumentCallback<?> documentCallback = new ReadSearchDocumentCallback<>(clazz, index);
|
SearchDocumentCallback<?> documentCallback = new ReadSearchDocumentCallback<>(clazz, index);
|
||||||
|
// noinspection unchecked
|
||||||
|
SearchDocumentResponse.EntityCreator<T> entityCreator = searchDocument -> ((Mono<T>) documentCallback
|
||||||
|
.toEntity(searchDocument)).toFuture();
|
||||||
|
|
||||||
return doFindForResponse(request, searchDocument -> documentCallback.toEntity(searchDocument).block());
|
return doFindForResponse(request, entityCreator);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,19 +898,18 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
* Customization hook on the actual execution result {@link Mono}. <br />
|
* Customization hook on the actual execution result {@link Mono}. <br />
|
||||||
*
|
*
|
||||||
* @param request the already prepared {@link SearchRequest} ready to be executed.
|
* @param request the already prepared {@link SearchRequest} ready to be executed.
|
||||||
* @param suggestEntityCreator
|
* @param entityCreator
|
||||||
* @return a {@link Mono} emitting the result of the operation converted to s {@link SearchDocumentResponse}.
|
* @return a {@link Mono} emitting the result of the operation converted to s {@link SearchDocumentResponse}.
|
||||||
*/
|
*/
|
||||||
protected Mono<SearchDocumentResponse> doFindForResponse(SearchRequest request,
|
protected <T> Mono<SearchDocumentResponse> doFindForResponse(SearchRequest request,
|
||||||
Function<SearchDocument, ? extends Object> suggestEntityCreator) {
|
SearchDocumentResponse.EntityCreator<T> entityCreator) {
|
||||||
|
|
||||||
if (QUERY_LOGGER.isDebugEnabled()) {
|
if (QUERY_LOGGER.isDebugEnabled()) {
|
||||||
QUERY_LOGGER.debug("Executing doFindForResponse: {}", request);
|
QUERY_LOGGER.debug("Executing doFindForResponse: {}", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mono.from(execute(client1 -> client1.searchForResponse(request))).map(searchResponse -> {
|
return Mono.from(execute(client -> client.searchForResponse(request)))
|
||||||
return SearchDocumentResponse.from(searchResponse, suggestEntityCreator);
|
.map(searchResponse -> SearchDocumentResponse.from(searchResponse, entityCreator));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
-4
@@ -123,7 +123,6 @@ public interface ReactiveSearchOperations {
|
|||||||
/**
|
/**
|
||||||
* Search the index for entities matching the given {@link Query query}.
|
* Search the index for entities matching the given {@link Query query}.
|
||||||
*
|
*
|
||||||
* @param <T>
|
|
||||||
* @param query must not be {@literal null}.
|
* @param query must not be {@literal null}.
|
||||||
* @param entityType must not be {@literal null}.
|
* @param entityType must not be {@literal null}.
|
||||||
* @param <T>
|
* @param <T>
|
||||||
@@ -137,7 +136,6 @@ public interface ReactiveSearchOperations {
|
|||||||
/**
|
/**
|
||||||
* Search the index for entities matching the given {@link Query query}.
|
* Search the index for entities matching the given {@link Query query}.
|
||||||
*
|
*
|
||||||
* @param <T>
|
|
||||||
* @param query must not be {@literal null}.
|
* @param query must not be {@literal null}.
|
||||||
* @param entityType must not be {@literal null}.
|
* @param entityType must not be {@literal null}.
|
||||||
* @param resultType the projection result type.
|
* @param resultType the projection result type.
|
||||||
@@ -150,7 +148,6 @@ public interface ReactiveSearchOperations {
|
|||||||
/**
|
/**
|
||||||
* Search the index for entities matching the given {@link Query query}.
|
* Search the index for entities matching the given {@link Query query}.
|
||||||
*
|
*
|
||||||
* @param <T>
|
|
||||||
* @param query must not be {@literal null}.
|
* @param query must not be {@literal null}.
|
||||||
* @param entityType must not be {@literal null}.
|
* @param entityType must not be {@literal null}.
|
||||||
* @param index the target index, must not be {@literal null}
|
* @param index the target index, must not be {@literal null}
|
||||||
@@ -165,7 +162,6 @@ public interface ReactiveSearchOperations {
|
|||||||
/**
|
/**
|
||||||
* Search the index for entities matching the given {@link Query query}.
|
* Search the index for entities matching the given {@link Query query}.
|
||||||
*
|
*
|
||||||
* @param <T>
|
|
||||||
* @param query must not be {@literal null}.
|
* @param query must not be {@literal null}.
|
||||||
* @param entityType must not be {@literal null}.
|
* @param entityType must not be {@literal null}.
|
||||||
* @param resultType the projection result type.
|
* @param resultType the projection result type.
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
|
||||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.document.Document;
|
import org.springframework.data.elasticsearch.core.document.Document;
|
||||||
import org.springframework.data.elasticsearch.core.document.NestedMetaData;
|
import org.springframework.data.elasticsearch.core.document.NestedMetaData;
|
||||||
@@ -45,6 +46,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Roman Puchkovskiy
|
* @author Roman Puchkovskiy
|
||||||
* @author Matt Gilene
|
* @author Matt Gilene
|
||||||
|
* @author Sascha Woo
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
class SearchHitMapping<T> {
|
class SearchHitMapping<T> {
|
||||||
@@ -194,7 +196,7 @@ class SearchHitMapping<T> {
|
|||||||
*/
|
*/
|
||||||
private SearchHits<?> mapInnerDocuments(SearchHits<SearchDocument> searchHits, Class<T> type) {
|
private SearchHits<?> mapInnerDocuments(SearchHits<SearchDocument> searchHits, Class<T> type) {
|
||||||
|
|
||||||
if (searchHits.getTotalHits() == 0) {
|
if (searchHits.isEmpty()) {
|
||||||
return searchHits;
|
return searchHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +241,7 @@ class SearchHitMapping<T> {
|
|||||||
searchHits.getSuggest());
|
searchHits.getSuggest());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.warn("Could not map inner_hits", e);
|
throw new UncategorizedElasticsearchException("Unable to convert inner hits.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchHits;
|
return searchHits;
|
||||||
|
|||||||
+4
-1
@@ -76,7 +76,10 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
|
|||||||
public Object write(Object value) {
|
public Object write(Object value) {
|
||||||
|
|
||||||
Assert.notNull(value, "value must not be null.");
|
Assert.notNull(value, "value must not be null.");
|
||||||
Assert.isInstanceOf(Range.class, value, "value must be instance of Range.");
|
|
||||||
|
if (!Range.class.isAssignableFrom(value.getClass())) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Range<T> range = (Range<T>) value;
|
Range<T> range = (Range<T>) value;
|
||||||
|
|||||||
+4
@@ -58,6 +58,10 @@ public class DatePropertyValueConverter extends AbstractPropertyValueConverter {
|
|||||||
@Override
|
@Override
|
||||||
public Object write(Object value) {
|
public Object write(Object value) {
|
||||||
|
|
||||||
|
if (!Date.class.isAssignableFrom(value.getClass())) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dateConverters.get(0).format((Date) value);
|
return dateConverters.get(0).format((Date) value);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
+12
-7
@@ -1256,14 +1256,19 @@ public class MappingElasticsearchConverter
|
|||||||
PropertyValueConverter propertyValueConverter = Objects
|
PropertyValueConverter propertyValueConverter = Objects
|
||||||
.requireNonNull(persistentProperty.getPropertyValueConverter());
|
.requireNonNull(persistentProperty.getPropertyValueConverter());
|
||||||
criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> {
|
criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> {
|
||||||
Object value = criteriaEntry.getValue();
|
|
||||||
if (value.getClass().isArray()) {
|
if (criteriaEntry.getKey().hasValue()) {
|
||||||
Object[] objects = (Object[]) value;
|
Object value = criteriaEntry.getValue();
|
||||||
for (int i = 0; i < objects.length; i++) {
|
|
||||||
objects[i] = propertyValueConverter.write(objects[i]);
|
if (value.getClass().isArray()) {
|
||||||
|
Object[] objects = (Object[]) value;
|
||||||
|
|
||||||
|
for (int i = 0; i < objects.length; i++) {
|
||||||
|
objects[i] = propertyValueConverter.write(objects[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
criteriaEntry.setValue(propertyValueConverter.write(value));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
criteriaEntry.setValue(propertyValueConverter.write(value));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -61,6 +61,10 @@ public class TemporalPropertyValueConverter extends AbstractPropertyValueConvert
|
|||||||
@Override
|
@Override
|
||||||
public Object write(Object value) {
|
public Object write(Object value) {
|
||||||
|
|
||||||
|
if (!TemporalAccessor.class.isAssignableFrom(value.getClass())) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dateConverters.get(0).format((TemporalAccessor) value);
|
return dateConverters.get(0).format((TemporalAccessor) value);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
+37
-11
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019-2021 the original author or authors.
|
* Copyright 2019-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,8 +17,11 @@ package org.springframework.data.elasticsearch.core.document;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.lucene.search.TotalHits;
|
import org.apache.lucene.search.TotalHits;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.common.text.Text;
|
import org.elasticsearch.common.text.Text;
|
||||||
@@ -38,13 +41,15 @@ import org.springframework.util.Assert;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This represents the complete search response from Elasticsearch, including the returned documents. Instances must be
|
* This represents the complete search response from Elasticsearch, including the returned documents. Instances must be
|
||||||
* created with the {@link #from(SearchResponse,Function)} method.
|
* created with the {@link #from(SearchResponse, EntityCreator)} method.
|
||||||
*
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class SearchDocumentResponse {
|
public class SearchDocumentResponse {
|
||||||
|
|
||||||
|
private static final Log LOGGER = LogFactory.getLog(SearchDocumentResponse.class);
|
||||||
|
|
||||||
private final long totalHits;
|
private final long totalHits;
|
||||||
private final String totalHitsRelation;
|
private final String totalHitsRelation;
|
||||||
private final float maxScore;
|
private final float maxScore;
|
||||||
@@ -98,12 +103,11 @@ public class SearchDocumentResponse {
|
|||||||
* creates a SearchDocumentResponse from the {@link SearchResponse}
|
* creates a SearchDocumentResponse from the {@link SearchResponse}
|
||||||
*
|
*
|
||||||
* @param searchResponse must not be {@literal null}
|
* @param searchResponse must not be {@literal null}
|
||||||
* @param suggestEntityCreator function to create an entity from a {@link SearchDocument}
|
* @param entityCreator function to create an entity from a {@link SearchDocument}
|
||||||
* @param <T> entity type
|
* @param <T> entity type
|
||||||
* @return the SearchDocumentResponse
|
* @return the SearchDocumentResponse
|
||||||
*/
|
*/
|
||||||
public static <T> SearchDocumentResponse from(SearchResponse searchResponse,
|
public static <T> SearchDocumentResponse from(SearchResponse searchResponse, EntityCreator<T> entityCreator) {
|
||||||
Function<SearchDocument, T> suggestEntityCreator) {
|
|
||||||
|
|
||||||
Assert.notNull(searchResponse, "searchResponse must not be null");
|
Assert.notNull(searchResponse, "searchResponse must not be null");
|
||||||
|
|
||||||
@@ -112,7 +116,7 @@ public class SearchDocumentResponse {
|
|||||||
Aggregations aggregations = searchResponse.getAggregations();
|
Aggregations aggregations = searchResponse.getAggregations();
|
||||||
org.elasticsearch.search.suggest.Suggest suggest = searchResponse.getSuggest();
|
org.elasticsearch.search.suggest.Suggest suggest = searchResponse.getSuggest();
|
||||||
|
|
||||||
return from(searchHits, scrollId, aggregations, suggest, suggestEntityCreator);
|
return from(searchHits, scrollId, aggregations, suggest, entityCreator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,14 +126,14 @@ public class SearchDocumentResponse {
|
|||||||
* @param scrollId scrollId
|
* @param scrollId scrollId
|
||||||
* @param aggregations aggregations
|
* @param aggregations aggregations
|
||||||
* @param suggestES the suggestion response from Elasticsearch
|
* @param suggestES the suggestion response from Elasticsearch
|
||||||
* @param suggestEntityCreator function to create an entity from a {@link SearchDocument}
|
* @param entityCreator function to create an entity from a {@link SearchDocument}
|
||||||
* @param <T> entity type
|
* @param <T> entity type
|
||||||
* @return the {@link SearchDocumentResponse}
|
* @return the {@link SearchDocumentResponse}
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
public static <T> SearchDocumentResponse from(SearchHits searchHits, @Nullable String scrollId,
|
public static <T> SearchDocumentResponse from(SearchHits searchHits, @Nullable String scrollId,
|
||||||
@Nullable Aggregations aggregations, @Nullable org.elasticsearch.search.suggest.Suggest suggestES,
|
@Nullable Aggregations aggregations, @Nullable org.elasticsearch.search.suggest.Suggest suggestES,
|
||||||
Function<SearchDocument, T> suggestEntityCreator) {
|
EntityCreator<T> entityCreator) {
|
||||||
|
|
||||||
TotalHits responseTotalHits = searchHits.getTotalHits();
|
TotalHits responseTotalHits = searchHits.getTotalHits();
|
||||||
|
|
||||||
@@ -153,14 +157,14 @@ public class SearchDocumentResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Suggest suggest = suggestFrom(suggestES, suggestEntityCreator);
|
Suggest suggest = suggestFrom(suggestES, entityCreator);
|
||||||
return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, searchDocuments, aggregations,
|
return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, searchDocuments, aggregations,
|
||||||
suggest);
|
suggest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static <T> Suggest suggestFrom(@Nullable org.elasticsearch.search.suggest.Suggest suggestES,
|
private static <T> Suggest suggestFrom(@Nullable org.elasticsearch.search.suggest.Suggest suggestES,
|
||||||
Function<SearchDocument, T> entityCreator) {
|
EntityCreator<T> entityCreator) {
|
||||||
|
|
||||||
if (suggestES == null) {
|
if (suggestES == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -219,7 +223,19 @@ public class SearchDocumentResponse {
|
|||||||
List<CompletionSuggestion.Entry.Option<T>> options = new ArrayList<>();
|
List<CompletionSuggestion.Entry.Option<T>> options = new ArrayList<>();
|
||||||
for (org.elasticsearch.search.suggest.completion.CompletionSuggestion.Entry.Option optionES : entryES) {
|
for (org.elasticsearch.search.suggest.completion.CompletionSuggestion.Entry.Option optionES : entryES) {
|
||||||
SearchDocument searchDocument = optionES.getHit() != null ? DocumentAdapters.from(optionES.getHit()) : null;
|
SearchDocument searchDocument = optionES.getHit() != null ? DocumentAdapters.from(optionES.getHit()) : null;
|
||||||
T hitEntity = searchDocument != null ? entityCreator.apply(searchDocument) : null;
|
|
||||||
|
T hitEntity = null;
|
||||||
|
|
||||||
|
if (searchDocument != null) {
|
||||||
|
try {
|
||||||
|
hitEntity = entityCreator.apply(searchDocument).get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (LOGGER.isWarnEnabled()) {
|
||||||
|
LOGGER.warn("Error creating entity from SearchDocument");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options.add(new CompletionSuggestion.Entry.Option<T>(textToString(optionES.getText()),
|
options.add(new CompletionSuggestion.Entry.Option<T>(textToString(optionES.getText()),
|
||||||
textToString(optionES.getHighlighted()), optionES.getScore(), optionES.collateMatch(),
|
textToString(optionES.getHighlighted()), optionES.getScore(), optionES.collateMatch(),
|
||||||
optionES.getContexts(), scoreDocFrom(optionES.getDoc()), searchDocument, hitEntity));
|
optionES.getContexts(), scoreDocFrom(optionES.getDoc()), searchDocument, hitEntity));
|
||||||
@@ -254,4 +270,14 @@ public class SearchDocumentResponse {
|
|||||||
private static String textToString(@Nullable Text text) {
|
private static String textToString(@Nullable Text text) {
|
||||||
return text != null ? text.string() : "";
|
return text != null ? text.string() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to convert a {@link SearchDocument} async into an entity. Asynchronous so that it can be used from the
|
||||||
|
* imperative and the reactive code.
|
||||||
|
*
|
||||||
|
* @param <T> the entity type
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface EntityCreator<T> extends Function<SearchDocument, CompletableFuture<T>> {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.springframework.data.elasticsearch.core.convert.GeoConverters;
|
|||||||
import org.springframework.data.elasticsearch.core.document.Document;
|
import org.springframework.data.elasticsearch.core.document.Document;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface definition for structures defined in <a href="https://geojson.org/>GeoJSON</a> format. copied from Spring
|
* Interface definition for structures defined in <a href="https://geojson.org/">GeoJSON</a> format. copied from Spring
|
||||||
* Data Mongodb
|
* Data Mongodb
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
|
|||||||
+9
-10
@@ -230,8 +230,7 @@ public class MappingBuilder {
|
|||||||
boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField);
|
boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField);
|
||||||
if (writeNestedProperties) {
|
if (writeNestedProperties) {
|
||||||
|
|
||||||
String type = nestedOrObjectField ? fieldType.toString().toLowerCase()
|
String type = nestedOrObjectField ? fieldType.getMappedName() : FieldType.Object.getMappedName();
|
||||||
: FieldType.Object.toString().toLowerCase();
|
|
||||||
|
|
||||||
ObjectNode nestedObjectNode = objectMapper.createObjectNode();
|
ObjectNode nestedObjectNode = objectMapper.createObjectNode();
|
||||||
nestedObjectNode.put(FIELD_PARAM_TYPE, type);
|
nestedObjectNode.put(FIELD_PARAM_TYPE, type);
|
||||||
@@ -247,9 +246,9 @@ public class MappingBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entity != null && entity.dynamic() != Dynamic.INHERIT) {
|
if (entity != null && entity.dynamic() != Dynamic.INHERIT) {
|
||||||
objectNode.put(TYPE_DYNAMIC, entity.dynamic().name().toLowerCase());
|
objectNode.put(TYPE_DYNAMIC, entity.dynamic().getMappedName());
|
||||||
} else if (dynamicMapping != null) {
|
} else if (dynamicMapping != null) {
|
||||||
objectNode.put(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
|
objectNode.put(TYPE_DYNAMIC, dynamicMapping.value().getMappedName());
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectNode propertiesNode = objectNode.putObject(FIELD_PROPERTIES);
|
ObjectNode propertiesNode = objectNode.putObject(FIELD_PROPERTIES);
|
||||||
@@ -418,7 +417,7 @@ public class MappingBuilder {
|
|||||||
|
|
||||||
ObjectNode contextNode = contextsNode.addObject();
|
ObjectNode contextNode = contextsNode.addObject();
|
||||||
contextNode.put(FIELD_CONTEXT_NAME, context.name());
|
contextNode.put(FIELD_CONTEXT_NAME, context.name());
|
||||||
contextNode.put(FIELD_CONTEXT_TYPE, context.type().name().toLowerCase());
|
contextNode.put(FIELD_CONTEXT_TYPE, context.type().getMappedName());
|
||||||
|
|
||||||
if (context.precision().length() > 0) {
|
if (context.precision().length() > 0) {
|
||||||
contextNode.put(FIELD_CONTEXT_PRECISION, context.precision());
|
contextNode.put(FIELD_CONTEXT_PRECISION, context.precision());
|
||||||
@@ -450,7 +449,7 @@ public class MappingBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
propertiesNode.set(property.getFieldName(), objectMapper.createObjectNode() //
|
propertiesNode.set(property.getFieldName(), objectMapper.createObjectNode() //
|
||||||
.put(FIELD_PARAM_TYPE, field.type().name().toLowerCase()) //
|
.put(FIELD_PARAM_TYPE, field.type().getMappedName()) //
|
||||||
.put(MAPPING_ENABLED, false) //
|
.put(MAPPING_ENABLED, false) //
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -479,9 +478,9 @@ public class MappingBuilder {
|
|||||||
|
|
||||||
if (nestedOrObjectField) {
|
if (nestedOrObjectField) {
|
||||||
if (annotation.dynamic() != Dynamic.INHERIT) {
|
if (annotation.dynamic() != Dynamic.INHERIT) {
|
||||||
fieldNode.put(TYPE_DYNAMIC, annotation.dynamic().name().toLowerCase());
|
fieldNode.put(TYPE_DYNAMIC, annotation.dynamic().getMappedName());
|
||||||
} else if (dynamicMapping != null) {
|
} else if (dynamicMapping != null) {
|
||||||
fieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
|
fieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().getMappedName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,9 +529,9 @@ public class MappingBuilder {
|
|||||||
|
|
||||||
if (nestedOrObjectField) {
|
if (nestedOrObjectField) {
|
||||||
if (annotation.mainField().dynamic() != Dynamic.INHERIT) {
|
if (annotation.mainField().dynamic() != Dynamic.INHERIT) {
|
||||||
mainFieldNode.put(TYPE_DYNAMIC, annotation.mainField().dynamic().name().toLowerCase());
|
mainFieldNode.put(TYPE_DYNAMIC, annotation.mainField().dynamic().getMappedName());
|
||||||
} else if (dynamicMapping != null) {
|
} else if (dynamicMapping != null) {
|
||||||
mainFieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
|
mainFieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().getMappedName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -237,9 +237,9 @@ public final class MappingParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type != FieldType.Auto) {
|
if (type != FieldType.Auto) {
|
||||||
objectNode.put(FIELD_PARAM_TYPE, type.toString().toLowerCase());
|
objectNode.put(FIELD_PARAM_TYPE, type.getMappedName());
|
||||||
|
|
||||||
if (type == FieldType.Date) {
|
if (type == FieldType.Date || type == FieldType.Date_Nanos || type == FieldType.Date_Range) {
|
||||||
List<String> formats = new ArrayList<>();
|
List<String> formats = new ArrayList<>();
|
||||||
|
|
||||||
// built-in formats
|
// built-in formats
|
||||||
|
|||||||
+2
-1
@@ -24,7 +24,8 @@ package org.springframework.data.elasticsearch.core.mapping;
|
|||||||
public interface PropertyValueConverter {
|
public interface PropertyValueConverter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a property value to an elasticsearch value.
|
* Converts a property value to an elasticsearch value. If the converter cannot convert the value, it must return a
|
||||||
|
* String representation.
|
||||||
*
|
*
|
||||||
* @param value the value to convert, must not be {@literal null}
|
* @param value the value to convert, must not be {@literal null}
|
||||||
* @return The elasticsearch property value, must not be {@literal null}
|
* @return The elasticsearch property value, must not be {@literal null}
|
||||||
|
|||||||
+6
-2
@@ -172,7 +172,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
|||||||
@Override
|
@Override
|
||||||
public boolean writeTypeHints() {
|
public boolean writeTypeHints() {
|
||||||
|
|
||||||
boolean writeTypeHints = contextConfiguration.writeTypeHints;
|
boolean writeTypeHints = contextConfiguration.getWriteTypeHints();
|
||||||
|
|
||||||
if (document != null) {
|
if (document != null) {
|
||||||
switch (document.writeTypeHint()) {
|
switch (document.writeTypeHint()) {
|
||||||
@@ -548,7 +548,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
|||||||
/**
|
/**
|
||||||
* Configuration settings passed in from the creating {@link SimpleElasticsearchMappingContext}.
|
* Configuration settings passed in from the creating {@link SimpleElasticsearchMappingContext}.
|
||||||
*/
|
*/
|
||||||
static class ContextConfiguration {
|
public static class ContextConfiguration {
|
||||||
|
|
||||||
private final FieldNamingStrategy fieldNamingStrategy;
|
private final FieldNamingStrategy fieldNamingStrategy;
|
||||||
private final boolean writeTypeHints;
|
private final boolean writeTypeHints;
|
||||||
@@ -561,6 +561,10 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
|||||||
public FieldNamingStrategy getFieldNamingStrategy() {
|
public FieldNamingStrategy getFieldNamingStrategy() {
|
||||||
return fieldNamingStrategy;
|
return fieldNamingStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getWriteTypeHints() {
|
||||||
|
return writeTypeHints;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -954,7 +954,23 @@ public class Criteria {
|
|||||||
/**
|
/**
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
NOT_EMPTY
|
NOT_EMPTY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this key does not have an associated value
|
||||||
|
* @since 4.4
|
||||||
|
*/
|
||||||
|
public boolean hasNoValue() {
|
||||||
|
return this == OperationKey.EXISTS || this == OperationKey.EMPTY || this == OperationKey.NOT_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this key does have an associated value
|
||||||
|
* @since 4.4
|
||||||
|
*/
|
||||||
|
public boolean hasValue() {
|
||||||
|
return !hasNoValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -967,9 +983,8 @@ public class Criteria {
|
|||||||
|
|
||||||
protected CriteriaEntry(OperationKey key) {
|
protected CriteriaEntry(OperationKey key) {
|
||||||
|
|
||||||
boolean keyIsValid = key == OperationKey.EXISTS || key == OperationKey.EMPTY || key == OperationKey.NOT_EMPTY;
|
Assert.isTrue(key.hasNoValue(),
|
||||||
Assert.isTrue(keyIsValid,
|
"key must be OperationKey.EXISTS, OperationKey.EMPTY or OperationKey.NOT_EMPTY for this call");
|
||||||
"key must be OperationKey.EXISTS, OperationKey.EMPTY or OperationKey.EMPTY for this call");
|
|
||||||
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import org.springframework.lang.Nullable;
|
|||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Farid Faoudi
|
* @author Farid Faoudi
|
||||||
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html>docs</a>
|
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html">docs</a>
|
||||||
*/
|
*/
|
||||||
public class UpdateQuery {
|
public class UpdateQuery {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Spring Data Elasticsearch 4.3 GA (2021.1.0)
|
Spring Data Elasticsearch 4.3.3 (2021.1.3)
|
||||||
Copyright (c) [2013-2021] Pivotal Software, Inc.
|
Copyright (c) [2013-2021] 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").
|
||||||
@@ -28,6 +28,9 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+27
@@ -2783,6 +2783,33 @@ public abstract class ElasticsearchTemplateTests {
|
|||||||
assertThat(searchHits.getSearchHit(1).getInnerHits("innerHits").getTotalHits()).isEqualTo(1);
|
assertThat(searchHits.getSearchHit(1).getInnerHits("innerHits").getTotalHits()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #1997
|
||||||
|
@DisplayName("should return document with inner hits size zero")
|
||||||
|
void shouldReturnDocumentWithInnerHitsSizeZero() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
SampleEntity sampleEntity = SampleEntity.builder().id(nextIdAsString()).message("message 1").rate(1)
|
||||||
|
.version(System.currentTimeMillis()).build();
|
||||||
|
|
||||||
|
List<IndexQuery> indexQueries = getIndexQueries(Arrays.asList(sampleEntity));
|
||||||
|
|
||||||
|
operations.bulkIndex(indexQueries, IndexCoordinates.of(indexNameProvider.indexName()));
|
||||||
|
|
||||||
|
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
||||||
|
.withCollapseBuilder(new CollapseBuilder("rate").setInnerHits(new InnerHitBuilder("innerHits").setSize(0)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// when
|
||||||
|
SearchHits<SampleEntity> searchHits = operations.search(searchQuery, SampleEntity.class,
|
||||||
|
IndexCoordinates.of(indexNameProvider.indexName()));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(searchHits).isNotNull();
|
||||||
|
assertThat(searchHits.getTotalHits()).isEqualTo(1);
|
||||||
|
assertThat(searchHits.getSearchHits()).hasSize(1);
|
||||||
|
assertThat(searchHits.getSearchHit(0).getContent().getMessage()).isEqualTo("message 1");
|
||||||
|
}
|
||||||
|
|
||||||
private IndexQuery getIndexQuery(SampleEntity sampleEntity) {
|
private IndexQuery getIndexQuery(SampleEntity sampleEntity) {
|
||||||
return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity)
|
return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity)
|
||||||
.withVersion(sampleEntity.getVersion()).build();
|
.withVersion(sampleEntity.getVersion()).build();
|
||||||
|
|||||||
+14
-1
@@ -66,6 +66,9 @@ import org.springframework.data.elasticsearch.core.geo.GeoJsonPolygon;
|
|||||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||||
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.Query;
|
||||||
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||||
import org.springframework.data.geo.Box;
|
import org.springframework.data.geo.Box;
|
||||||
import org.springframework.data.geo.Circle;
|
import org.springframework.data.geo.Circle;
|
||||||
@@ -1496,6 +1499,16 @@ public class MappingElasticsearchConverterUnitTests {
|
|||||||
assertThat(entity.getDontConvert()).isEqualTo("Monty Python's Flying Circus");
|
assertThat(entity.getDontConvert()).isEqualTo("Monty Python's Flying Circus");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2080
|
||||||
|
@DisplayName("should not try to call property converter on updating criteria exists")
|
||||||
|
void shouldNotTryToCallPropertyConverterOnUpdatingCriteriaExists() {
|
||||||
|
|
||||||
|
// don't care if the query makes no sense, we just add all criteria without values
|
||||||
|
Query query = new CriteriaQuery(Criteria.where("fieldWithClassBasedConverter").exists().empty().notEmpty());
|
||||||
|
|
||||||
|
mappingElasticsearchConverter.updateQuery(query, EntityWithCustomValueConverters.class);
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> writeToMap(Object source) {
|
private Map<String, Object> writeToMap(Object source) {
|
||||||
|
|
||||||
Document sink = Document.create();
|
Document sink = Document.create();
|
||||||
@@ -2429,6 +2442,7 @@ public class MappingElasticsearchConverterUnitTests {
|
|||||||
return reverse(value);
|
return reverse(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
private static String reverse(Object o) {
|
private static String reverse(Object o) {
|
||||||
|
|
||||||
@@ -2436,5 +2450,4 @@ public class MappingElasticsearchConverterUnitTests {
|
|||||||
|
|
||||||
return new StringBuilder().append(o.toString()).reverse().toString();
|
return new StringBuilder().append(o.toString()).reverse().toString();
|
||||||
}
|
}
|
||||||
// endregion
|
|
||||||
}
|
}
|
||||||
|
|||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.core.convert;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
import static org.junit.jupiter.params.provider.Arguments.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Named;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchPersistentEntity;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
public class PropertyValueConvertersUnitTests {
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}") // #2018
|
||||||
|
@MethodSource("propertyValueConverters")
|
||||||
|
@DisplayName("should return original object on write if it cannot be converted")
|
||||||
|
void shouldReturnOriginalObjectOnWriteIfItCannotBeConverted(PropertyValueConverter converter) {
|
||||||
|
|
||||||
|
NoConverterForThisClass value = new NoConverterForThisClass();
|
||||||
|
|
||||||
|
Object written = converter.write(value);
|
||||||
|
|
||||||
|
assertThat(written).isEqualTo(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> propertyValueConverters() {
|
||||||
|
|
||||||
|
SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext();
|
||||||
|
SimpleElasticsearchPersistentEntity<?> persistentEntity = context
|
||||||
|
.getRequiredPersistentEntity(NoConverterForThisClass.class);
|
||||||
|
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("property");
|
||||||
|
|
||||||
|
List<PropertyValueConverter> converters = new ArrayList<>();
|
||||||
|
|
||||||
|
converters.add(new DatePropertyValueConverter(persistentProperty,
|
||||||
|
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||||
|
converters.add(new DateRangePropertyValueConverter(persistentProperty,
|
||||||
|
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||||
|
converters.add(new NumberRangePropertyValueConverter(persistentProperty));
|
||||||
|
converters.add(new TemporalPropertyValueConverter(persistentProperty,
|
||||||
|
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||||
|
converters.add(new TemporalRangePropertyValueConverter(persistentProperty,
|
||||||
|
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
|
||||||
|
|
||||||
|
return converters.stream().map(propertyValueConverter -> arguments(
|
||||||
|
Named.of(propertyValueConverter.getClass().getSimpleName(), propertyValueConverter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class NoConverterForThisClass {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Nullable Long property;
|
||||||
|
}
|
||||||
|
}
|
||||||
+307
-123
@@ -38,10 +38,14 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.assertj.core.data.Percentage;
|
import org.assertj.core.data.Percentage;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.annotation.Id;
|
||||||
import org.springframework.data.elasticsearch.annotations.*;
|
import org.springframework.data.elasticsearch.annotations.*;
|
||||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||||
@@ -57,6 +61,7 @@ import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
|||||||
import org.springframework.data.elasticsearch.core.suggest.Completion;
|
import org.springframework.data.elasticsearch.core.suggest.Completion;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
|
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
||||||
|
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
|
||||||
import org.springframework.data.geo.Box;
|
import org.springframework.data.geo.Box;
|
||||||
import org.springframework.data.geo.Circle;
|
import org.springframework.data.geo.Circle;
|
||||||
import org.springframework.data.geo.Point;
|
import org.springframework.data.geo.Point;
|
||||||
@@ -79,10 +84,25 @@ import org.springframework.test.context.ContextConfiguration;
|
|||||||
* @author Morgan Lutz
|
* @author Morgan Lutz
|
||||||
*/
|
*/
|
||||||
@SpringIntegrationTest
|
@SpringIntegrationTest
|
||||||
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class })
|
@ContextConfiguration(classes = { MappingBuilderIntegrationTests.Config.class })
|
||||||
public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import({ ElasticsearchRestTemplateConfiguration.class })
|
||||||
|
static class Config {
|
||||||
|
@Bean
|
||||||
|
IndexNameProvider indexNameProvider() {
|
||||||
|
return new IndexNameProvider("mapping-builder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired private ElasticsearchOperations operations;
|
@Autowired private ElasticsearchOperations operations;
|
||||||
|
@Autowired IndexNameProvider indexNameProvider;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void before() {
|
||||||
|
indexNameProvider.increment();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(java.lang.Integer.MAX_VALUE)
|
@Order(java.lang.Integer.MAX_VALUE)
|
||||||
@@ -132,8 +152,7 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
@Test // DATAES-76
|
@Test // DATAES-76
|
||||||
public void shouldAddSampleInheritedEntityDocumentToIndex() {
|
public void shouldAddSampleInheritedEntityDocumentToIndex() {
|
||||||
// given
|
// given
|
||||||
IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder");
|
IndexOperations indexOps = operations.indexOps(SampleInheritedEntity.class);
|
||||||
IndexOperations indexOps = operations.indexOps(index);
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
indexOps.create();
|
indexOps.create();
|
||||||
@@ -142,11 +161,10 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
String message = "msg";
|
String message = "msg";
|
||||||
String id = "abc";
|
String id = "abc";
|
||||||
operations.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(),
|
operations.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(),
|
||||||
index);
|
IndexCoordinates.of(indexNameProvider.indexName()));
|
||||||
operations.indexOps(SampleInheritedEntity.class).refresh();
|
|
||||||
|
|
||||||
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
|
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
|
||||||
SearchHits<SampleInheritedEntity> result = operations.search(searchQuery, SampleInheritedEntity.class, index);
|
SearchHits<SampleInheritedEntity> result = operations.search(searchQuery, SampleInheritedEntity.class);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).hasSize(1);
|
assertThat(result).hasSize(1);
|
||||||
@@ -163,7 +181,7 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
IndexOperations indexOpsUser = operations.indexOps(User.class);
|
IndexOperations indexOpsUser = operations.indexOps(User.class);
|
||||||
indexOpsUser.create();
|
indexOpsUser.create();
|
||||||
indexOpsUser.putMapping(User.class);
|
indexOpsUser.putMapping(User.class);
|
||||||
|
indexNameProvider.increment();
|
||||||
IndexOperations indexOpsGroup = operations.indexOps(Group.class);
|
IndexOperations indexOpsGroup = operations.indexOps(Group.class);
|
||||||
indexOpsGroup.create();
|
indexOpsGroup.create();
|
||||||
indexOpsGroup.putMapping(Group.class);
|
indexOpsGroup.putMapping(Group.class);
|
||||||
@@ -336,11 +354,19 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2024
|
||||||
|
@DisplayName("should map all field type values")
|
||||||
|
void shouldMapAllFieldTypeValues() {
|
||||||
|
operations.indexOps(EntityWithAllTypes.class).createWithMapping();
|
||||||
|
}
|
||||||
|
|
||||||
// region entities
|
// region entities
|
||||||
@Document(indexName = "ignore-above-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class IgnoreAboveEntity {
|
static class IgnoreAboveEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Keyword, ignoreAbove = 10) private String message;
|
@Id private String id;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Keyword, ignoreAbove = 10) private String message;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -365,57 +391,76 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "fieldname-index")
|
||||||
static class IdEntity {
|
static class IdEntity {
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class TextEntity {
|
static class TextEntity {
|
||||||
|
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
|
|
||||||
@Field(name = "text-property", type = FieldType.Text) //
|
@Field(name = "text-property", type = FieldType.Text) //
|
||||||
@Nullable private String textProperty;
|
@Nullable private String textProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class MappingEntity {
|
static class MappingEntity {
|
||||||
|
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
|
|
||||||
@Field("mapping-property") @Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") //
|
@Field("mapping-property")
|
||||||
|
@Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") //
|
||||||
@Nullable private byte[] mappingProperty;
|
@Nullable private byte[] mappingProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class GeoPointEntity {
|
static class GeoPointEntity {
|
||||||
|
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
|
|
||||||
@Nullable @Field("geopoint-property") private GeoPoint geoPoint;
|
@Nullable
|
||||||
|
@Field("geopoint-property") private GeoPoint geoPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class CircularEntity {
|
static class CircularEntity {
|
||||||
|
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
|
|
||||||
@Nullable @Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) //
|
@Nullable
|
||||||
|
@Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) //
|
||||||
private CircularEntity circularProperty;
|
private CircularEntity circularProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class CompletionEntity {
|
static class CompletionEntity {
|
||||||
|
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
|
|
||||||
@Nullable @Field("completion-property") @CompletionField(maxInputLength = 100) //
|
@Nullable
|
||||||
|
@Field("completion-property")
|
||||||
|
@CompletionField(maxInputLength = 100) //
|
||||||
private Completion suggest;
|
private Completion suggest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fieldname-index")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class MultiFieldEntity {
|
static class MultiFieldEntity {
|
||||||
|
|
||||||
@Nullable @Id @Field("id-property") private String id;
|
@Nullable
|
||||||
|
@Id
|
||||||
|
@Field("id-property") private String id;
|
||||||
|
|
||||||
@Nullable //
|
@Nullable //
|
||||||
@MultiField(mainField = @Field(name = "main-field", type = FieldType.Text, analyzer = "whitespace"),
|
@MultiField(mainField = @Field(name = "main-field", type = FieldType.Text, analyzer = "whitespace"),
|
||||||
@@ -425,13 +470,17 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-book-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class Book {
|
static class Book {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
@Nullable private String name;
|
@Nullable private String name;
|
||||||
@Nullable @Field(type = FieldType.Object) private Author author;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Nested) private Map<Integer, Collection<String>> buckets = new HashMap<>();
|
@Field(type = FieldType.Object) private Author author;
|
||||||
@Nullable @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"),
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested) private Map<Integer, Collection<String>> buckets = new HashMap<>();
|
||||||
|
@Nullable
|
||||||
|
@MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"),
|
||||||
otherFields = { @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop",
|
otherFields = { @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop",
|
||||||
searchAnalyzer = "standard") }) private String description;
|
searchAnalyzer = "standard") }) private String description;
|
||||||
|
|
||||||
@@ -481,11 +530,12 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-simple-recursive-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class SimpleRecursiveEntity {
|
static class SimpleRecursiveEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Object,
|
@Id private String id;
|
||||||
ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject;
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object, ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -506,12 +556,16 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-copy-to-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class CopyToEntity {
|
static class CopyToEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Keyword, copyTo = "name") private String firstName;
|
@Id private String id;
|
||||||
@Nullable @Field(type = FieldType.Keyword, copyTo = "name") private String lastName;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Keyword) private String name;
|
@Field(type = FieldType.Keyword, copyTo = "name") private String firstName;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Keyword, copyTo = "name") private String lastName;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Keyword) private String name;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -550,12 +604,15 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-normalizer-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
@Setting(settingPath = "/settings/test-normalizer.json")
|
@Setting(settingPath = "/settings/test-normalizer.json")
|
||||||
static class NormalizerEntity {
|
static class NormalizerEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Keyword, normalizer = "lower_case_normalizer") private String name;
|
@Id private String id;
|
||||||
@Nullable @MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "lower_case",
|
@Nullable
|
||||||
|
@Field(type = FieldType.Keyword, normalizer = "lower_case_normalizer") private String name;
|
||||||
|
@Nullable
|
||||||
|
@MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "lower_case",
|
||||||
type = FieldType.Keyword, normalizer = "lower_case_normalizer") }) private String description;
|
type = FieldType.Keyword, normalizer = "lower_case_normalizer") }) private String description;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -610,10 +667,11 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-sample-inherited-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class SampleInheritedEntity extends AbstractInheritedEntity {
|
static class SampleInheritedEntity extends AbstractInheritedEntity {
|
||||||
|
|
||||||
@Nullable @Field(type = Text, index = false, store = true, analyzer = "standard") private String message;
|
@Nullable
|
||||||
|
@Field(type = Text, index = false, store = true, analyzer = "standard") private String message;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
@@ -656,11 +714,13 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-stock-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class StockPrice {
|
static class StockPrice {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
@Nullable private String symbol;
|
@Nullable private String symbol;
|
||||||
@Nullable @Field(type = FieldType.Double) private BigDecimal price;
|
@Nullable
|
||||||
|
@Field(type = FieldType.Double) private BigDecimal price;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -691,8 +751,10 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class AbstractInheritedEntity {
|
static class AbstractInheritedEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.date_time, index = false) private Date createdDate;
|
@Id private String id;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Date, format = DateFormat.date_time, index = false) private Date createdDate;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -713,21 +775,27 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-geo-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class GeoEntity {
|
static class GeoEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
// geo shape - Spring Data
|
// geo shape - Spring Data
|
||||||
@Nullable private Box box;
|
@Nullable private Box box;
|
||||||
@Nullable private Circle circle;
|
@Nullable private Circle circle;
|
||||||
@Nullable private Polygon polygon;
|
@Nullable private Polygon polygon;
|
||||||
// geo point - Custom implementation + Spring Data
|
// geo point - Custom implementation + Spring Data
|
||||||
@Nullable @GeoPointField private Point pointA;
|
@Nullable
|
||||||
|
@GeoPointField private Point pointA;
|
||||||
@Nullable private GeoPoint pointB;
|
@Nullable private GeoPoint pointB;
|
||||||
@Nullable @GeoPointField private String pointC;
|
@Nullable
|
||||||
@Nullable @GeoPointField private double[] pointD;
|
@GeoPointField private String pointC;
|
||||||
|
@Nullable
|
||||||
|
@GeoPointField private double[] pointD;
|
||||||
// geo shape, until e have the classes for this, us a strng
|
// geo shape, until e have the classes for this, us a strng
|
||||||
@Nullable @GeoShapeField private String shape1;
|
@Nullable
|
||||||
@Nullable @GeoShapeField(coerce = true, ignoreMalformed = true, ignoreZValue = false,
|
@GeoShapeField private String shape1;
|
||||||
|
@Nullable
|
||||||
|
@GeoShapeField(coerce = true, ignoreMalformed = true, ignoreZValue = false,
|
||||||
orientation = GeoShapeField.Orientation.clockwise) private String shape2;
|
orientation = GeoShapeField.Orientation.clockwise) private String shape2;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -821,17 +889,21 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-user-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
|
|
||||||
static class User {
|
static class User {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
|
|
||||||
@Field(type = FieldType.Nested, ignoreFields = { "users" }) private Set<Group> groups = new HashSet<>();
|
@Field(type = FieldType.Nested, ignoreFields = { "users" }) private Set<Group> groups = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-group-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
|
|
||||||
static class Group {
|
static class Group {
|
||||||
|
|
||||||
@Nullable @Id String id;
|
@Nullable
|
||||||
|
@Id String id;
|
||||||
|
|
||||||
@Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set<User> users = new HashSet<>();
|
@Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set<User> users = new HashSet<>();
|
||||||
}
|
}
|
||||||
@@ -848,11 +920,14 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "completion")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
|
|
||||||
static class CompletionDocument {
|
static class CompletionDocument {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @CompletionField(contexts = { @CompletionContext(name = "location",
|
@Id private String id;
|
||||||
type = CompletionContext.ContextMappingType.GEO, path = "proppath") }) private Completion suggest;
|
@Nullable
|
||||||
|
@CompletionField(contexts = { @CompletionContext(name = "location", type = CompletionContext.ContextMappingType.GEO,
|
||||||
|
path = "proppath") }) private Completion suggest;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -873,9 +948,10 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-index-entity-with-seq-no-primary-term-mapping-builder")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class EntityWithSeqNoPrimaryTerm {
|
static class EntityWithSeqNoPrimaryTerm {
|
||||||
@Nullable @Field(type = Object) private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
@Nullable
|
||||||
|
@Field(type = Object) private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public SeqNoPrimaryTerm getSeqNoPrimaryTerm() {
|
public SeqNoPrimaryTerm getSeqNoPrimaryTerm() {
|
||||||
@@ -888,10 +964,14 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class RankFeatureEntity {
|
static class RankFeatureEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Rank_Feature) private Integer pageRank;
|
@Id private String id;
|
||||||
@Nullable @Field(type = FieldType.Rank_Feature, positiveScoreImpact = false) private Integer urlLength;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Rank_Features) private Map<String, Integer> topics;
|
@Field(type = FieldType.Rank_Feature) private Integer pageRank;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Rank_Feature, positiveScoreImpact = false) private Integer urlLength;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Rank_Features) private Map<String, Integer> topics;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -930,18 +1010,25 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "termvectors-test")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class TermVectorFieldEntity {
|
static class TermVectorFieldEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Text, termVector = TermVector.no) private String no;
|
@Id private String id;
|
||||||
@Nullable @Field(type = FieldType.Text, termVector = TermVector.yes) private String yes;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Text, termVector = TermVector.with_positions) private String with_positions;
|
@Field(type = FieldType.Text, termVector = TermVector.no) private String no;
|
||||||
@Nullable @Field(type = FieldType.Text, termVector = TermVector.with_offsets) private String with_offsets;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Text,
|
@Field(type = FieldType.Text, termVector = TermVector.yes) private String yes;
|
||||||
termVector = TermVector.with_positions_offsets) private String with_positions_offsets;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Text,
|
@Field(type = FieldType.Text, termVector = TermVector.with_positions) private String with_positions;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Text, termVector = TermVector.with_offsets) private String with_offsets;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Text, termVector = TermVector.with_positions_offsets) private String with_positions_offsets;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Text,
|
||||||
termVector = TermVector.with_positions_payloads) private String with_positions_payloads;
|
termVector = TermVector.with_positions_payloads) private String with_positions_payloads;
|
||||||
@Nullable @Field(type = FieldType.Text,
|
@Nullable
|
||||||
|
@Field(type = FieldType.Text,
|
||||||
termVector = TermVector.with_positions_offsets_payloads) private String with_positions_offsets_payloads;
|
termVector = TermVector.with_positions_offsets_payloads) private String with_positions_offsets_payloads;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -1017,10 +1104,12 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "wildcard-test")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class WildcardEntity {
|
static class WildcardEntity {
|
||||||
@Nullable @Field(type = Wildcard) private String wildcardWithoutParams;
|
@Nullable
|
||||||
@Nullable @Field(type = Wildcard, nullValue = "WILD", ignoreAbove = 42) private String wildcardWithParams;
|
@Field(type = Wildcard) private String wildcardWithoutParams;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = Wildcard, nullValue = "WILD", ignoreAbove = 42) private String wildcardWithParams;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getWildcardWithoutParams() {
|
public String getWildcardWithoutParams() {
|
||||||
@@ -1041,11 +1130,13 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "disabled-entity-mapping")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
@Mapping(enabled = false)
|
@Mapping(enabled = false)
|
||||||
static class DisabledMappingEntity {
|
static class DisabledMappingEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = Text) private String text;
|
@Id private String id;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = Text) private String text;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -1068,9 +1159,13 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
|
|
||||||
@Document(indexName = "disabled-property-mapping")
|
@Document(indexName = "disabled-property-mapping")
|
||||||
static class DisabledMappingProperty {
|
static class DisabledMappingProperty {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = Text) private String text;
|
@Id private String id;
|
||||||
@Nullable @Mapping(enabled = false) @Field(type = Object) private Object object;
|
@Nullable
|
||||||
|
@Field(type = Text) private String text;
|
||||||
|
@Nullable
|
||||||
|
@Mapping(enabled = false)
|
||||||
|
@Field(type = Object) private Object object;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -1100,10 +1195,12 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "densevector-test")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class DenseVectorEntity {
|
static class DenseVectorEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
@Nullable @Field(type = Dense_Vector, dims = 3) private float[] dense_vector;
|
@Id private String id;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = Dense_Vector, dims = 3) private float[] dense_vector;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getId() {
|
public String getId() {
|
||||||
@@ -1124,15 +1221,19 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "dynamic-mapping-annotation")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
@DynamicMapping(DynamicMappingValue.False)
|
@DynamicMapping(DynamicMappingValue.False)
|
||||||
static class DynamicMappingAnnotationEntity {
|
static class DynamicMappingAnnotationEntity {
|
||||||
|
|
||||||
@Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author;
|
@Nullable
|
||||||
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
|
@DynamicMapping(DynamicMappingValue.Strict)
|
||||||
type = FieldType.Object) private Map<String, Object> objectMap;
|
@Field(type = FieldType.Object) private Author author;
|
||||||
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
|
@Nullable
|
||||||
type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap;
|
@DynamicMapping(DynamicMappingValue.False)
|
||||||
|
@Field(type = FieldType.Object) private Map<String, Object> objectMap;
|
||||||
|
@Nullable
|
||||||
|
@DynamicMapping(DynamicMappingValue.False)
|
||||||
|
@Field(type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Author getAuthor() {
|
public Author getAuthor() {
|
||||||
@@ -1144,57 +1245,140 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "dynamic-mapping", dynamic = Dynamic.FALSE)
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class DynamicMappingEntity {
|
static class DynamicMappingEntity {
|
||||||
|
|
||||||
@Nullable @Field(type = FieldType.Object) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object) //
|
||||||
private Map<String, Object> objectInherit;
|
private Map<String, Object> objectInherit;
|
||||||
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.FALSE) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object, dynamic = Dynamic.FALSE) //
|
||||||
private Map<String, Object> objectFalse;
|
private Map<String, Object> objectFalse;
|
||||||
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.TRUE) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object, dynamic = Dynamic.TRUE) //
|
||||||
private Map<String, Object> objectTrue;
|
private Map<String, Object> objectTrue;
|
||||||
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.STRICT) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object, dynamic = Dynamic.STRICT) //
|
||||||
private Map<String, Object> objectStrict;
|
private Map<String, Object> objectStrict;
|
||||||
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.RUNTIME) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object, dynamic = Dynamic.RUNTIME) //
|
||||||
private Map<String, Object> objectRuntime;
|
private Map<String, Object> objectRuntime;
|
||||||
@Nullable @Field(type = FieldType.Nested) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested) //
|
||||||
private List<Map<String, Object>> nestedObjectInherit;
|
private List<Map<String, Object>> nestedObjectInherit;
|
||||||
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.FALSE) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested, dynamic = Dynamic.FALSE) //
|
||||||
private List<Map<String, Object>> nestedObjectFalse;
|
private List<Map<String, Object>> nestedObjectFalse;
|
||||||
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.TRUE) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested, dynamic = Dynamic.TRUE) //
|
||||||
private List<Map<String, Object>> nestedObjectTrue;
|
private List<Map<String, Object>> nestedObjectTrue;
|
||||||
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.STRICT) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested, dynamic = Dynamic.STRICT) //
|
||||||
private List<Map<String, Object>> nestedObjectStrict;
|
private List<Map<String, Object>> nestedObjectStrict;
|
||||||
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.RUNTIME) //
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested, dynamic = Dynamic.RUNTIME) //
|
||||||
private List<Map<String, Object>> nestedObjectRuntime;
|
private List<Map<String, Object>> nestedObjectRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "dynamic-detection-mapping-true")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
@Mapping(dateDetection = Mapping.Detection.TRUE, numericDetection = Mapping.Detection.TRUE,
|
@Mapping(dateDetection = Mapping.Detection.TRUE, numericDetection = Mapping.Detection.TRUE,
|
||||||
dynamicDateFormats = { "MM/dd/yyyy" })
|
dynamicDateFormats = { "MM/dd/yyyy" })
|
||||||
private static class DynamicDetectionMapping {
|
private static class DynamicDetectionMapping {
|
||||||
@Id @Nullable private String id;
|
@Id
|
||||||
|
@Nullable private String id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "runtime-fields")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
@Mapping(runtimeFieldsPath = "/mappings/runtime-fields.json")
|
@Mapping(runtimeFieldsPath = "/mappings/runtime-fields.json")
|
||||||
private static class RuntimeFieldEntity {
|
private static class RuntimeFieldEntity {
|
||||||
@Id @Nullable private String id;
|
@Id
|
||||||
@Field(type = Date, format = DateFormat.epoch_millis, name = "@timestamp") @Nullable private Instant timestamp;
|
@Nullable private String id;
|
||||||
|
@Field(type = Date, format = DateFormat.epoch_millis, name = "@timestamp")
|
||||||
|
@Nullable private Instant timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "fields-excluded-from-source")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
private static class ExcludedFieldEntity {
|
private static class ExcludedFieldEntity {
|
||||||
@Id @Nullable private String id;
|
@Id
|
||||||
@Nullable @Field(name = "excluded-date", type = Date, format = DateFormat.date,
|
@Nullable private String id;
|
||||||
|
@Nullable
|
||||||
|
@Field(name = "excluded-date", type = Date, format = DateFormat.date,
|
||||||
excludeFromSource = true) private LocalDate excludedDate;
|
excludeFromSource = true) private LocalDate excludedDate;
|
||||||
@Nullable @Field(type = Nested) private NestedExcludedFieldEntity nestedEntity;
|
@Nullable
|
||||||
|
@Field(type = Nested) private NestedExcludedFieldEntity nestedEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class NestedExcludedFieldEntity {
|
private static class NestedExcludedFieldEntity {
|
||||||
@Nullable @Field(name = "excluded-text", type = Text, excludeFromSource = true) private String excludedText;
|
@Nullable
|
||||||
|
@Field(name = "excluded-text", type = Text, excludeFromSource = true) private String excludedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
|
private static class EntityWithAllTypes {
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Auto) String autoField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Text) String textField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Keyword) String keywordField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Long) String longField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Integer) String integerField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Short) String shortField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Byte) String byteField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Double) String doubleField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Float) String floatField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Half_Float) String halfFloatField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Scaled_Float) String scaledFloatField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Date) String dateField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Date_Nanos) String dateNanosField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Boolean) String booleanField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Binary) String binaryField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Integer_Range) String integerRangeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Float_Range) String floatRangeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Long_Range) String longRangeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Double_Range) String doubleRangeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Date_Range) String dateRangeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Ip_Range) String ipRangeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Object) String objectField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Nested) String nestedField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Ip) String ipField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.TokenCount, analyzer = "standard") String tokenCountField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Percolator) String percolatorField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Flattened) String flattenedField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Search_As_You_Type) String searchAsYouTypeField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Rank_Feature) String rankFeatureField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Rank_Features) String rankFeaturesField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Wildcard) String wildcardField;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Dense_Vector, dims = 1) String denseVectorField;
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+49
@@ -42,6 +42,7 @@ import org.springframework.data.annotation.Id;
|
|||||||
import org.springframework.data.annotation.Transient;
|
import org.springframework.data.annotation.Transient;
|
||||||
import org.springframework.data.elasticsearch.annotations.*;
|
import org.springframework.data.elasticsearch.annotations.*;
|
||||||
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
|
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
|
||||||
|
import org.springframework.data.elasticsearch.core.Range;
|
||||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
|
||||||
@@ -721,6 +722,29 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
|||||||
assertEquals(expected, mapping, false);
|
assertEquals(expected, mapping, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2102
|
||||||
|
@DisplayName("should write date formats for date range fields")
|
||||||
|
void shouldWriteDateFormatsForDateRangeFields() throws JSONException {
|
||||||
|
|
||||||
|
String expected = "{\n" + //
|
||||||
|
" \"properties\": {\n" + //
|
||||||
|
" \"_class\": {\n" + //
|
||||||
|
" \"type\": \"keyword\",\n" + //
|
||||||
|
" \"index\": false,\n" + //
|
||||||
|
" \"doc_values\": false\n" + //
|
||||||
|
" },\n" + //
|
||||||
|
" \"field2\": {\n" + //
|
||||||
|
" \"type\": \"date_range\",\n" + //
|
||||||
|
" \"format\": \"date\"\n" + //
|
||||||
|
" }\n" + //
|
||||||
|
" }\n" + //
|
||||||
|
"}\n"; //
|
||||||
|
|
||||||
|
String mapping = getMappingBuilder().buildPropertyMapping(DateRangeEntity.class);
|
||||||
|
|
||||||
|
assertEquals(expected, mapping, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test // #1454
|
@Test // #1454
|
||||||
@DisplayName("should write type hints when context is configured to do so")
|
@DisplayName("should write type hints when context is configured to do so")
|
||||||
void shouldWriteTypeHintsWhenContextIsConfiguredToDoSo() throws JSONException {
|
void shouldWriteTypeHintsWhenContextIsConfiguredToDoSo() throws JSONException {
|
||||||
@@ -1911,6 +1935,31 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class DateRangeEntity {
|
||||||
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = Date_Range, format = DateFormat.date) private Range<LocalDateTime> field2;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(@Nullable String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Range<LocalDateTime> getField2() {
|
||||||
|
return field2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField2(@Nullable Range<LocalDateTime> field2) {
|
||||||
|
this.field2 = field2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Document(indexName = "magazine")
|
@Document(indexName = "magazine")
|
||||||
private static class Magazine {
|
private static class Magazine {
|
||||||
@Id @Nullable private String id;
|
@Id @Nullable private String id;
|
||||||
|
|||||||
+18
-9
@@ -265,23 +265,30 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
|||||||
|
|
||||||
// region entities
|
// region entities
|
||||||
static class FieldNameProperty {
|
static class FieldNameProperty {
|
||||||
@Nullable @Field(name = "by-name") String fieldProperty;
|
@Nullable
|
||||||
|
@Field(name = "by-name") String fieldProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FieldValueProperty {
|
static class FieldValueProperty {
|
||||||
@Nullable @Field(value = "by-value") String fieldProperty;
|
@Nullable
|
||||||
|
@Field(value = "by-value") String fieldProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class MultiFieldProperty {
|
static class MultiFieldProperty {
|
||||||
@Nullable @MultiField(mainField = @Field("mainfield"),
|
@Nullable
|
||||||
|
@MultiField(mainField = @Field("mainfield"),
|
||||||
otherFields = { @InnerField(suffix = "suff", type = FieldType.Keyword) }) String mainfieldProperty;
|
otherFields = { @InnerField(suffix = "suff", type = FieldType.Keyword) }) String mainfieldProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DatesProperty {
|
static class DatesProperty {
|
||||||
@Nullable @Field(type = FieldType.Date, format = {}, pattern = "dd.MM.uuuu") LocalDate localDate;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime;
|
@Field(type = FieldType.Date, format = {}, pattern = "dd.MM.uuuu") LocalDate localDate;
|
||||||
@Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) Date legacyDate;
|
@Nullable
|
||||||
@Nullable @Field(type = FieldType.Date, format = {}, pattern = "dd.MM.uuuu") List<LocalDate> localDateList;
|
@Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Date, format = DateFormat.basic_date_time) Date legacyDate;
|
||||||
|
@Nullable
|
||||||
|
@Field(type = FieldType.Date, format = {}, pattern = "dd.MM.uuuu") List<LocalDate> localDateList;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SeqNoPrimaryTermProperty {
|
static class SeqNoPrimaryTermProperty {
|
||||||
@@ -344,8 +351,10 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
|||||||
|
|
||||||
private static class EntityWithCustomValueConverters {
|
private static class EntityWithCustomValueConverters {
|
||||||
@Id private String id;
|
@Id private String id;
|
||||||
@Nullable @ValueConverter(ClassBasedValueConverter.class) private String fieldWithClassBasedConverter;
|
@Nullable
|
||||||
@Nullable @ValueConverter(EnumBasedValueConverter.class) private String fieldWithEnumBasedConverter;
|
@ValueConverter(ClassBasedValueConverter.class) private String fieldWithClassBasedConverter;
|
||||||
|
@Nullable
|
||||||
|
@ValueConverter(EnumBasedValueConverter.class) private String fieldWithEnumBasedConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ClassBasedValueConverter implements PropertyValueConverter {
|
private static class ClassBasedValueConverter implements PropertyValueConverter {
|
||||||
|
|||||||
+23
-14
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2021 the original author or authors.
|
* Copyright 2021-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core.suggest;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -39,8 +40,8 @@ import org.springframework.data.elasticsearch.annotations.Document;
|
|||||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.Query;
|
||||||
import org.springframework.data.elasticsearch.core.suggest.response.CompletionSuggestion;
|
import org.springframework.data.elasticsearch.core.suggest.response.CompletionSuggestion;
|
||||||
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
|
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
|
||||||
@@ -86,13 +87,11 @@ public class ReactiveElasticsearchTemplateSuggestIntegrationTests {
|
|||||||
@DisplayName("should find suggestions for given prefix completion")
|
@DisplayName("should find suggestions for given prefix completion")
|
||||||
void shouldFindSuggestionsForGivenPrefixCompletion() {
|
void shouldFindSuggestionsForGivenPrefixCompletion() {
|
||||||
|
|
||||||
loadCompletionObjectEntities();
|
loadCompletionObjectEntities() //
|
||||||
|
.flatMap(unused -> {
|
||||||
NativeSearchQuery query = new NativeSearchQueryBuilder().withSuggestBuilder(new SuggestBuilder()
|
Query query = getSuggestQuery("test-suggest", "suggest", "m");
|
||||||
.addSuggestion("test-suggest", SuggestBuilders.completionSuggestion("suggest").prefix("m", Fuzziness.AUTO)))
|
return operations.suggest(query, CompletionEntity.class);
|
||||||
.build();
|
}) //
|
||||||
|
|
||||||
operations.suggest(query, CompletionEntity.class) //
|
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.assertNext(suggest -> {
|
.assertNext(suggest -> {
|
||||||
Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> suggestion = suggest
|
Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> suggestion = suggest
|
||||||
@@ -105,13 +104,21 @@ public class ReactiveElasticsearchTemplateSuggestIntegrationTests {
|
|||||||
assertThat(options).hasSize(2);
|
assertThat(options).hasSize(2);
|
||||||
assertThat(options.get(0).getText()).isIn("Marchand", "Mohsin");
|
assertThat(options.get(0).getText()).isIn("Marchand", "Mohsin");
|
||||||
assertThat(options.get(1).getText()).isIn("Marchand", "Mohsin");
|
assertThat(options.get(1).getText()).isIn("Marchand", "Mohsin");
|
||||||
|
|
||||||
}) //
|
}) //
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Query getSuggestQuery(String suggestionName, String fieldName, String prefix) {
|
||||||
|
return new NativeSearchQueryBuilder() //
|
||||||
|
.withSuggestBuilder(new SuggestBuilder() //
|
||||||
|
.addSuggestion(suggestionName, //
|
||||||
|
SuggestBuilders.completionSuggestion(fieldName) //
|
||||||
|
.prefix(prefix, Fuzziness.AUTO))) //
|
||||||
|
.build(); //
|
||||||
|
}
|
||||||
|
|
||||||
// region helper functions
|
// region helper functions
|
||||||
private void loadCompletionObjectEntities() {
|
private Mono<CompletionEntity> loadCompletionObjectEntities() {
|
||||||
|
|
||||||
CompletionEntity rizwan_idrees = new CompletionEntityBuilder("1").name("Rizwan Idrees")
|
CompletionEntity rizwan_idrees = new CompletionEntityBuilder("1").name("Rizwan Idrees")
|
||||||
.suggest(new String[] { "Rizwan Idrees" }).build();
|
.suggest(new String[] { "Rizwan Idrees" }).build();
|
||||||
@@ -124,7 +131,7 @@ public class ReactiveElasticsearchTemplateSuggestIntegrationTests {
|
|||||||
List<CompletionEntity> entities = new ArrayList<>(
|
List<CompletionEntity> entities = new ArrayList<>(
|
||||||
Arrays.asList(rizwan_idrees, franck_marchand, mohsin_husen, artur_konczak));
|
Arrays.asList(rizwan_idrees, franck_marchand, mohsin_husen, artur_konczak));
|
||||||
IndexCoordinates index = IndexCoordinates.of(indexNameProvider.indexName());
|
IndexCoordinates index = IndexCoordinates.of(indexNameProvider.indexName());
|
||||||
operations.saveAll(entities, index).blockLast();
|
return operations.saveAll(entities, index).last();
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@@ -132,11 +139,13 @@ public class ReactiveElasticsearchTemplateSuggestIntegrationTests {
|
|||||||
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
static class CompletionEntity {
|
static class CompletionEntity {
|
||||||
|
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
|
|
||||||
@Nullable private String name;
|
@Nullable private String name;
|
||||||
|
|
||||||
@Nullable @CompletionField(maxInputLength = 100) private Completion suggest;
|
@Nullable
|
||||||
|
@CompletionField(maxInputLength = 100) private Completion suggest;
|
||||||
|
|
||||||
private CompletionEntity() {}
|
private CompletionEntity() {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user