mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-12 21:33:27 +00:00
parent
170648d467
commit
45e9fd7f5a
@ -69,6 +69,7 @@ import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchC
|
|||||||
import org.springframework.data.elasticsearch.core.document.Document;
|
import org.springframework.data.elasticsearch.core.document.Document;
|
||||||
import org.springframework.data.elasticsearch.core.document.SearchDocument;
|
import org.springframework.data.elasticsearch.core.document.SearchDocument;
|
||||||
import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCallback;
|
import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCallback;
|
||||||
|
import org.springframework.data.elasticsearch.core.event.ReactiveAfterLoadCallback;
|
||||||
import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback;
|
import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback;
|
||||||
import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback;
|
import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||||
@ -1159,6 +1160,17 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
|
|
||||||
return Mono.just(entity);
|
return Mono.just(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected <T> Mono<Document> maybeCallbackAfterLoad(Document document, Class<T> type,
|
||||||
|
IndexCoordinates indexCoordinates) {
|
||||||
|
|
||||||
|
if (entityCallbacks != null) {
|
||||||
|
return entityCallbacks.callback(ReactiveAfterLoadCallback.class, document, type, indexCoordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Mono.just(document);
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region routing
|
// region routing
|
||||||
@ -1206,12 +1218,20 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
T entity = reader.read(type, document);
|
return maybeCallbackAfterLoad(document, type, index) //
|
||||||
IndexedObjectInformation indexedObjectInformation = IndexedObjectInformation.of(
|
.flatMap(documentAfterLoad -> {
|
||||||
document.hasId() ? document.getId() : null, document.getSeqNo(), document.getPrimaryTerm(),
|
|
||||||
document.getVersion());
|
T entity = reader.read(type, documentAfterLoad);
|
||||||
entity = updateIndexedObject(entity, indexedObjectInformation);
|
|
||||||
return maybeCallAfterConvert(entity, document, index);
|
IndexedObjectInformation indexedObjectInformation = IndexedObjectInformation.of( //
|
||||||
|
documentAfterLoad.hasId() ? documentAfterLoad.getId() : null, //
|
||||||
|
documentAfterLoad.getSeqNo(), //
|
||||||
|
documentAfterLoad.getPrimaryTerm(), //
|
||||||
|
documentAfterLoad.getVersion()); //
|
||||||
|
entity = updateIndexedObject(entity, indexedObjectInformation);
|
||||||
|
|
||||||
|
return maybeCallAfterConvert(entity, documentAfterLoad, index);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverte
|
|||||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||||
import org.springframework.data.elasticsearch.core.document.Document;
|
import org.springframework.data.elasticsearch.core.document.Document;
|
||||||
import org.springframework.data.elasticsearch.core.event.AfterConvertCallback;
|
import org.springframework.data.elasticsearch.core.event.AfterConvertCallback;
|
||||||
|
import org.springframework.data.elasticsearch.core.event.AfterLoadCallback;
|
||||||
import org.springframework.data.elasticsearch.core.event.AfterSaveCallback;
|
import org.springframework.data.elasticsearch.core.event.AfterSaveCallback;
|
||||||
import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback;
|
import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||||
@ -690,6 +691,15 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected <T> Document maybeCallbackAfterLoad(Document document, Class<T> type, IndexCoordinates indexCoordinates) {
|
||||||
|
|
||||||
|
if (entityCallbacks != null) {
|
||||||
|
return entityCallbacks.callback(AfterLoadCallback.class, document, type, indexCoordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
protected void updateIndexedObjectsWithQueries(List<?> queries,
|
protected void updateIndexedObjectsWithQueries(List<?> queries,
|
||||||
@ -736,13 +746,18 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
if (document == null) {
|
if (document == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Document documentAfterLoad = maybeCallbackAfterLoad(document, type, index);
|
||||||
|
|
||||||
T entity = reader.read(type, document);
|
T entity = reader.read(type, documentAfterLoad);
|
||||||
IndexedObjectInformation indexedObjectInformation = IndexedObjectInformation.of(
|
|
||||||
document.hasId() ? document.getId() : null, document.getSeqNo(), document.getPrimaryTerm(),
|
IndexedObjectInformation indexedObjectInformation = IndexedObjectInformation.of( //
|
||||||
document.getVersion());
|
documentAfterLoad.hasId() ? documentAfterLoad.getId() : null, //
|
||||||
|
documentAfterLoad.getSeqNo(), //
|
||||||
|
documentAfterLoad.getPrimaryTerm(), //
|
||||||
|
documentAfterLoad.getVersion()); //
|
||||||
entity = updateIndexedObject(entity, indexedObjectInformation);
|
entity = updateIndexedObject(entity, indexedObjectInformation);
|
||||||
return maybeCallbackAfterConvert(entity, document, index);
|
|
||||||
|
return maybeCallbackAfterConvert(entity, documentAfterLoad, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.event;
|
||||||
|
|
||||||
|
import org.springframework.data.elasticsearch.core.document.Document;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
|
import org.springframework.data.mapping.callback.EntityCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback being invoked after a {@link Document} is read from Elasticsearch and before it is converted into a domain
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
* @since 4.4
|
||||||
|
* @see org.springframework.data.mapping.callback.EntityCallbacks
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface AfterLoadCallback<T> extends EntityCallback<Document> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either the
|
||||||
|
* same or a modified instance of the {@link Document} object.
|
||||||
|
*
|
||||||
|
* @param document the document.
|
||||||
|
* @param indexCoordinates of the index the document was read from.
|
||||||
|
* @return a possible modified or new {@link Document}.
|
||||||
|
*/
|
||||||
|
Document onAfterLoad(Document document, Class<T> type, IndexCoordinates indexCoordinates);
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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.event;
|
||||||
|
|
||||||
|
import org.reactivestreams.Publisher;
|
||||||
|
import org.springframework.data.elasticsearch.core.document.Document;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
|
import org.springframework.data.mapping.callback.EntityCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback being invoked after a {@link Document} is read from Elasticsearch and before it is converted into a domain
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
* @since 4.4
|
||||||
|
* @see org.springframework.data.mapping.callback.EntityCallbacks
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ReactiveAfterLoadCallback<T> extends EntityCallback<Document> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either the
|
||||||
|
* same or a modified instance of the {@link Document} object.
|
||||||
|
*
|
||||||
|
* @param document the document.
|
||||||
|
* @param indexCoordinates of the index the document was read from.
|
||||||
|
* @return a possible modified or new {@link Document}.
|
||||||
|
*/
|
||||||
|
Publisher<Document> onAfterLoad(Document document, Class<T> type, IndexCoordinates indexCoordinates);
|
||||||
|
}
|
@ -29,6 +29,7 @@ import org.mockito.ArgumentCaptor;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.annotation.ReadOnlyProperty;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
import org.springframework.data.elasticsearch.annotations.JoinTypeRelation;
|
import org.springframework.data.elasticsearch.annotations.JoinTypeRelation;
|
||||||
import org.springframework.data.elasticsearch.annotations.JoinTypeRelations;
|
import org.springframework.data.elasticsearch.annotations.JoinTypeRelations;
|
||||||
@ -73,6 +74,19 @@ abstract class ElasticsearchOperationsCallbackIntegrationTests {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
static class SampleEntityAfterLoadCallback implements AfterLoadCallback<SampleEntity> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.springframework.data.elasticsearch.core.document.Document onAfterLoad(
|
||||||
|
org.springframework.data.elasticsearch.core.document.Document document, Class<SampleEntity> type,
|
||||||
|
IndexCoordinates indexCoordinates) {
|
||||||
|
|
||||||
|
document.put("className", document.get("_class"));
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@ -214,12 +228,30 @@ abstract class ElasticsearchOperationsCallbackIntegrationTests {
|
|||||||
assertThat(capturedIndexQuery.getPrimaryTerm()).isEqualTo(seqNoPrimaryTerm.getPrimaryTerm());
|
assertThat(capturedIndexQuery.getPrimaryTerm()).isEqualTo(seqNoPrimaryTerm.getPrimaryTerm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2009
|
||||||
|
@DisplayName("should invoke after load callback")
|
||||||
|
void shouldInvokeAfterLoadCallback() {
|
||||||
|
|
||||||
|
SampleEntity entity = new SampleEntity("1", "test");
|
||||||
|
operations.save(entity);
|
||||||
|
|
||||||
|
SampleEntity loaded = operations.get(entity.getId(), SampleEntity.class);
|
||||||
|
|
||||||
|
assertThat(loaded).isNotNull();
|
||||||
|
assertThat(loaded.className).isEqualTo(SampleEntity.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
@Document(indexName = INDEX)
|
@Document(indexName = INDEX)
|
||||||
static class SampleEntity {
|
static class SampleEntity {
|
||||||
@Nullable @Id private String id;
|
@Nullable
|
||||||
|
@Id private String id;
|
||||||
@Nullable private String text;
|
@Nullable private String text;
|
||||||
|
|
||||||
@Nullable @JoinTypeRelations(relations = {
|
@ReadOnlyProperty
|
||||||
|
@Nullable private String className;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@JoinTypeRelations(relations = {
|
||||||
@JoinTypeRelation(parent = "question", children = { "answer" }) }) private JoinField<String> joinField;
|
@JoinTypeRelation(parent = "question", children = { "answer" }) }) private JoinField<String> joinField;
|
||||||
|
|
||||||
@Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
@Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm;
|
||||||
|
@ -22,11 +22,13 @@ import reactor.test.StepVerifier;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
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.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.annotation.ReadOnlyProperty;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||||
import org.springframework.data.elasticsearch.core.IndexOperations;
|
import org.springframework.data.elasticsearch.core.IndexOperations;
|
||||||
@ -35,6 +37,7 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
|||||||
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
|
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
|
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
@ -49,6 +52,7 @@ public class ReactiveElasticsearchOperationsCallbackTest {
|
|||||||
@Configuration
|
@Configuration
|
||||||
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class, ElasticsearchRestTemplateConfiguration.class })
|
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class, ElasticsearchRestTemplateConfiguration.class })
|
||||||
static class Config {
|
static class Config {
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
static class SampleEntityBeforeConvertCallback implements ReactiveBeforeConvertCallback<SampleEntity> {
|
static class SampleEntityBeforeConvertCallback implements ReactiveBeforeConvertCallback<SampleEntity> {
|
||||||
@Override
|
@Override
|
||||||
@ -58,6 +62,20 @@ public class ReactiveElasticsearchOperationsCallbackTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
static class SampleEntityAfterLoadCallback
|
||||||
|
implements ReactiveAfterLoadCallback<ElasticsearchOperationsCallbackIntegrationTests.SampleEntity> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<org.springframework.data.elasticsearch.core.document.Document> onAfterLoad(
|
||||||
|
org.springframework.data.elasticsearch.core.document.Document document,
|
||||||
|
Class<ElasticsearchOperationsCallbackIntegrationTests.SampleEntity> type, IndexCoordinates indexCoordinates) {
|
||||||
|
|
||||||
|
document.put("className", document.get("_class"));
|
||||||
|
return Mono.just(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired private ReactiveElasticsearchOperations operations;
|
@Autowired private ReactiveElasticsearchOperations operations;
|
||||||
@ -88,11 +106,29 @@ public class ReactiveElasticsearchOperationsCallbackTest {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // #2009
|
||||||
|
@DisplayName("should invoke after load callback")
|
||||||
|
void shouldInvokeAfterLoadCallback() {
|
||||||
|
|
||||||
|
SampleEntity entity = new SampleEntity("1", "test");
|
||||||
|
|
||||||
|
operations.save(entity) //
|
||||||
|
.then(operations.get(entity.getId(), SampleEntity.class)) //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.consumeNextWith(loaded -> { //
|
||||||
|
assertThat(loaded).isNotNull(); //
|
||||||
|
assertThat(loaded.className).isEqualTo(SampleEntity.class.getName()); //
|
||||||
|
}).verifyComplete(); //
|
||||||
|
}
|
||||||
|
|
||||||
@Document(indexName = "test-operations-reactive-callback")
|
@Document(indexName = "test-operations-reactive-callback")
|
||||||
static class SampleEntity {
|
static class SampleEntity {
|
||||||
@Id private String id;
|
@Id private String id;
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
|
@ReadOnlyProperty
|
||||||
|
@Nullable private String className;
|
||||||
|
|
||||||
public SampleEntity(String id, String text) {
|
public SampleEntity(String id, String text) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
@ -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;
|
||||||
@ -54,6 +55,7 @@ import org.springframework.lang.Nullable;
|
|||||||
@SuppressWarnings("SpringJavaAutowiredMembersInspection")
|
@SuppressWarnings("SpringJavaAutowiredMembersInspection")
|
||||||
@SpringIntegrationTest
|
@SpringIntegrationTest
|
||||||
public class SuggestReactiveTemplateIntegrationTests {
|
public class SuggestReactiveTemplateIntegrationTests {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
|
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
|
||||||
static class Config {
|
static class Config {
|
||||||
@ -86,32 +88,34 @@ public class SuggestReactiveTemplateIntegrationTests {
|
|||||||
@DisplayName("should find suggestions for given prefix completion")
|
@DisplayName("should find suggestions for given prefix completion")
|
||||||
void shouldFindSuggestionsForGivenPrefixCompletion() {
|
void shouldFindSuggestionsForGivenPrefixCompletion() {
|
||||||
|
|
||||||
loadCompletionObjectEntities();
|
loadCompletionObjectEntities().map(unused -> {
|
||||||
|
|
||||||
NativeSearchQuery query = new NativeSearchQueryBuilder().withSuggestBuilder(new SuggestBuilder()
|
NativeSearchQuery query = new NativeSearchQueryBuilder().withSuggestBuilder(new SuggestBuilder()
|
||||||
.addSuggestion("test-suggest", SuggestBuilders.completionSuggestion("suggest").prefix("m", Fuzziness.AUTO)))
|
.addSuggestion("test-suggest", SuggestBuilders.completionSuggestion("suggest").prefix("m", Fuzziness.AUTO)))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
operations.suggest(query, CompletionEntity.class) //
|
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
|
||||||
.getSuggestion("test-suggest");
|
.getSuggestion("test-suggest");
|
||||||
assertThat(suggestion).isNotNull();
|
assertThat(suggestion).isNotNull();
|
||||||
assertThat(suggestion).isInstanceOf(CompletionSuggestion.class);
|
assertThat(suggestion).isInstanceOf(CompletionSuggestion.class);
|
||||||
// noinspection unchecked
|
// noinspection unchecked
|
||||||
List<CompletionSuggestion.Entry.Option<CompletionIntegrationTests.AnnotatedCompletionEntity>> options = ((CompletionSuggestion<CompletionIntegrationTests.AnnotatedCompletionEntity>) suggestion)
|
List<CompletionSuggestion.Entry.Option<CompletionIntegrationTests.AnnotatedCompletionEntity>> options = ((CompletionSuggestion<CompletionIntegrationTests.AnnotatedCompletionEntity>) suggestion)
|
||||||
.getEntries().get(0).getOptions();
|
.getEntries().get(0).getOptions();
|
||||||
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();
|
||||||
|
return Mono.empty();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// region helper functions
|
// region helper functions
|
||||||
private void loadCompletionObjectEntities() {
|
private Mono<Void> 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 +128,7 @@ public class SuggestReactiveTemplateIntegrationTests {
|
|||||||
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).then();
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@ -132,11 +136,13 @@ public class SuggestReactiveTemplateIntegrationTests {
|
|||||||
@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() {}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user