DATAES-976 - Implement CrudRepository and ReactiveCrudRepository.deleteAllById(Iterable<ID> ids).

Original pull request: #554.
This commit is contained in:
Jens Schauder 2020-11-12 15:20:22 +01:00 committed by Mark Paluch
parent b17999f8fa
commit 749270ba25
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
4 changed files with 98 additions and 7 deletions

View File

@ -66,6 +66,7 @@ import org.springframework.util.Assert;
* @author Murali Chevuri
* @author Peter-Josef Meisch
* @author Aleksei Arsenev
* @author Jens Schauder
*/
public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchRepository<T, ID> {
@ -315,6 +316,31 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
});
}
@Override
public void deleteAllById(Iterable<? extends ID> ids) {
Assert.notNull(ids, "Cannot delete 'null' list.");
IndexCoordinates indexCoordinates = getIndexCoordinates();
IdsQueryBuilder idsQueryBuilder = idsQuery();
for (ID id : ids) {
if (id != null) {
idsQueryBuilder.addIds(stringIdRepresentation(id));
}
}
if (idsQueryBuilder.ids().isEmpty()) {
return;
}
Query query = new NativeSearchQueryBuilder().withQuery(idsQueryBuilder).build();
executeAndRefresh((OperationsCallback<Void>) operations -> {
operations.delete(query, entityClass, indexCoordinates);
return null;
});
}
private void doDelete(@Nullable ID id, @Nullable String routing, IndexCoordinates indexCoordinates) {
if (id != null) {

View File

@ -35,12 +35,14 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilde
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.data.util.Streamable;
import org.springframework.util.Assert;
/**
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @author Aleksei Arsenev
* @author Jens Schauder
* @since 3.2
*/
public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveElasticsearchRepository<T, ID> {
@ -52,7 +54,7 @@ public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveEla
private final ReactiveIndexOperations indexOperations;
public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation<T, ID> entityInformation,
ReactiveElasticsearchOperations operations) {
ReactiveElasticsearchOperations operations) {
Assert.notNull(entityInformation, "EntityInformation must not be null!");
Assert.notNull(operations, "ElasticsearchOperations must not be null!");
@ -211,6 +213,21 @@ public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveEla
return deleteAll(Flux.fromIterable(entities));
}
@Override
public Mono<Void> deleteAllById(Iterable<? extends ID> ids) {
Assert.notNull(ids, "Ids must not be null!");
return Mono.just(Streamable.of(ids) //
.map(this::convertId).toList() //
).map(objects -> new StringQuery(QueryBuilders.idsQuery() //
.addIds(objects.toArray(new String[0])) //
.toString()) //
).flatMap(
query -> operations.delete(query, entityInformation.getJavaType(), entityInformation.getIndexCoordinates())) //
.then(doRefresh());
}
@Override
public Mono<Void> deleteAll(Publisher<? extends T> entityStream) {

View File

@ -15,6 +15,7 @@
*/
package org.springframework.data.elasticsearch.repository.support;
import static java.util.Arrays.*;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import static org.springframework.data.elasticsearch.core.query.Query.*;
@ -64,6 +65,7 @@ import org.springframework.test.context.ContextConfiguration;
/**
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @author Jens Schauder
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { SimpleReactiveElasticsearchRepositoryTests.Config.class })
@ -107,7 +109,7 @@ public class SimpleReactiveElasticsearchRepositoryTests {
public void saveShouldComputeMultipleEntities() {
repository
.saveAll(Arrays.asList(SampleEntity.builder().build(), SampleEntity.builder().build(),
.saveAll(asList(SampleEntity.builder().build(), SampleEntity.builder().build(),
SampleEntity.builder().build())) //
.map(SampleEntity::getId) //
.flatMap(this::documentWithIdExistsInIndex) //
@ -167,7 +169,7 @@ public class SimpleReactiveElasticsearchRepositoryTests {
@Test // DATAES-519
public void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() {
repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete();
repository.findAllById(asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete();
}
@Test // DATAES-519
@ -178,7 +180,7 @@ public class SimpleReactiveElasticsearchRepositoryTests {
SampleEntity.builder().id("id-three").build()) //
.block();
repository.findAllById(Arrays.asList("id-one", "id-two")) //
repository.findAllById(asList("id-one", "id-two")) //
.as(StepVerifier::create)//
.expectNextMatches(entity -> entity.getId().equals("id-one") || entity.getId().equals("id-two")) //
.expectNextMatches(entity -> entity.getId().equals("id-one") || entity.getId().equals("id-two")) //
@ -193,7 +195,7 @@ public class SimpleReactiveElasticsearchRepositoryTests {
SampleEntity.builder().id("id-three").build()) //
.block();
repository.findAllById(Arrays.asList("can't", "touch", "this")) //
repository.findAllById(asList("can't", "touch", "this")) //
.as(StepVerifier::create)//
.verifyComplete();
}
@ -380,6 +382,18 @@ public class SimpleReactiveElasticsearchRepositoryTests {
assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
}
@Test // DATAES-976
public void deleteAllByIdShouldDeleteEntry() {
SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build();
bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted) //
.block();
repository.deleteAllById(asList(toBeDeleted.getId())).as(StepVerifier::create).verifyComplete();
assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
}
@Test // DATAES-519
public void deleteShouldDeleteEntry() {
@ -402,7 +416,7 @@ public class SimpleReactiveElasticsearchRepositoryTests {
bulkIndex(toBeDeleted, hangInThere, toBeDeleted2) //
.block();
repository.deleteAll(Arrays.asList(toBeDeleted, toBeDeleted2)).as(StepVerifier::create).verifyComplete();
repository.deleteAll(asList(toBeDeleted, toBeDeleted2)).as(StepVerifier::create).verifyComplete();
assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
assertThat(documentWithIdExistsInIndex(toBeDeleted2.getId()).block()).isFalse();
@ -547,7 +561,7 @@ public class SimpleReactiveElasticsearchRepositoryTests {
}
Mono<Void> bulkIndex(SampleEntity... entities) {
return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then();
return operations.saveAll(asList(entities), IndexCoordinates.of(INDEX)).then();
}
interface ReactiveSampleEntityRepository extends ReactiveCrudRepository<SampleEntity, String> {

View File

@ -406,6 +406,40 @@ public class SimpleElasticsearchRepositoryIntegrationTests {
assertThat(result).isEqualTo(1L);
}
@Test //DATAES-976
public void shouldDeleteAllById() {
// given
String id1 = nextIdAsString();
SampleEntity sampleEntity1 = new SampleEntity();
sampleEntity1.setId(id1);
sampleEntity1.setMessage("hello world 1");
sampleEntity1.setAvailable(true);
sampleEntity1.setVersion(System.currentTimeMillis());
String id2 = nextIdAsString();
SampleEntity sampleEntity2 = new SampleEntity();
sampleEntity2.setId(id2);
sampleEntity2.setMessage("hello world 2");
sampleEntity2.setAvailable(true);
sampleEntity2.setVersion(System.currentTimeMillis());
String id3 = nextIdAsString();
SampleEntity sampleEntity3 = new SampleEntity();
sampleEntity3.setId(id3);
sampleEntity3.setMessage("hello world 3");
sampleEntity3.setAvailable(false);
sampleEntity3.setVersion(System.currentTimeMillis());
repository.saveAll(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
// when
repository.deleteAllById(Arrays.asList(id1, id3));
// then
assertThat(repository.findAll()).extracting(SampleEntity::getId).containsExactly(id2);
}
@Test
public void shouldDeleteByMessageAndReturnList() {