Skip to content

Commit 4a90020

Browse files
committed
DATAES-157 - support deleteBy operation
1 parent 01a67ee commit 4a90020

File tree

6 files changed

+184
-1
lines changed

6 files changed

+184
-1
lines changed

src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,14 @@ public interface ElasticsearchOperations {
340340
*/
341341
String delete(String indexName, String type, String id);
342342

343+
344+
/**
345+
* Delete all records matching the criteria
346+
*
347+
* @param clazz
348+
* @param criteriaQuery
349+
*/
350+
<T> void delete(CriteriaQuery criteriaQuery, Class<T> clazz);
343351
/**
344352
* Delete the one object with provided id
345353
*

src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,15 @@ public void delete(DeleteQuery deleteQuery) {
585585
.setQuery(deleteQuery.getQuery()).execute().actionGet();
586586
}
587587

588+
@Override
589+
public <T> void delete(CriteriaQuery criteriaQuery, Class<T> clazz) {
590+
QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria());
591+
Assert.notNull(elasticsearchQuery, "Query can not be null.");
592+
DeleteQuery deleteQuery = new DeleteQuery();
593+
deleteQuery.setQuery(elasticsearchQuery);
594+
delete(deleteQuery, clazz);
595+
}
596+
588597
@Override
589598
public String scan(SearchQuery searchQuery, long scrollTimeInMillis, boolean noFields) {
590599
Assert.notNull(searchQuery.getIndices(), "No index defined for Query");

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.data.mapping.context.MappingContext;
2424
import org.springframework.data.repository.query.ParametersParameterAccessor;
2525
import org.springframework.data.repository.query.parser.PartTree;
26+
import org.springframework.util.ClassUtils;
2627

2728
/**
2829
* ElasticsearchPartQuery
@@ -46,7 +47,11 @@ public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOper
4647
public Object execute(Object[] parameters) {
4748
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
4849
CriteriaQuery query = createQuery(accessor);
49-
if (queryMethod.isPageQuery()) {
50+
if(tree.isDelete()) {
51+
Object result = countOrGetDocumentsForDelete(query, accessor);
52+
elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType());
53+
return result;
54+
} else if (queryMethod.isPageQuery()) {
5055
query.setPageable(accessor.getPageable());
5156
return elasticsearchOperations.queryForPage(query, queryMethod.getEntityInformation().getJavaType());
5257
} else if (queryMethod.isCollectionQuery()) {
@@ -63,6 +68,26 @@ public Object execute(Object[] parameters) {
6368
return elasticsearchOperations.queryForObject(query, queryMethod.getEntityInformation().getJavaType());
6469
}
6570

71+
private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) {
72+
73+
Object result = null;
74+
75+
if (queryMethod.isCollectionQuery()) {
76+
if (accessor.getPageable() == null) {
77+
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
78+
query.setPageable(new PageRequest(0, Math.max(1, itemCount)));
79+
} else {
80+
query.setPageable(accessor.getPageable());
81+
}
82+
result = elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType());
83+
}
84+
85+
if (ClassUtils.isAssignable(Number.class, queryMethod.getReturnedObjectType())) {
86+
result = elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
87+
}
88+
return result;
89+
}
90+
6691
public CriteriaQuery createQuery(ParametersParameterAccessor accessor) {
6792
return new ElasticsearchQueryCreator(tree, accessor, mappingContext).createQuery();
6893
}

src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,28 @@ public void shouldExecuteGivenCriteriaQuery() {
559559
assertThat(sampleEntity1, is(notNullValue()));
560560
}
561561

562+
@Test
563+
public void shouldDeleteGivenCriteriaQuery() {
564+
// given
565+
String documentId = randomNumeric(5);
566+
SampleEntity sampleEntity = new SampleEntityBuilder(documentId).message("test message")
567+
.version(System.currentTimeMillis()).build();
568+
569+
IndexQuery indexQuery = getIndexQuery(sampleEntity);
570+
571+
elasticsearchTemplate.index(indexQuery);
572+
elasticsearchTemplate.refresh(SampleEntity.class, true);
573+
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test"));
574+
575+
// when
576+
elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class);
577+
// then
578+
StringQuery stringQuery = new StringQuery(matchAllQuery().toString());
579+
List<SampleEntity> sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class);
580+
581+
assertThat(sampleEntities.size(), is(0));
582+
}
583+
562584
@Test
563585
public void shouldReturnSpecifiedFields() {
564586
// given

src/test/java/org/springframework/data/elasticsearch/repositories/sample/SampleElasticsearchRepository.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.elasticsearch.repositories.sample;
1717

18+
import java.util.List;
19+
1820
import org.springframework.data.elasticsearch.entities.SampleEntity;
1921
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
2022

@@ -24,4 +26,9 @@
2426
*/
2527
public interface SampleElasticsearchRepository extends ElasticsearchRepository<SampleEntity, String> {
2628

29+
long deleteById(String id);
30+
List<SampleEntity> deleteByAvailable(boolean available);
31+
List<SampleEntity> deleteByMessage(String message);
32+
void deleteByType(String type);
33+
2734
}

src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepositoryTests.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,118 @@ public void shouldDeleteAll() {
299299
assertThat(sampleEntities.getTotalElements(), equalTo(0L));
300300
}
301301

302+
@Test
303+
public void shouldDeleteById() {
304+
// given
305+
String documentId = randomNumeric(5);
306+
SampleEntity sampleEntity = new SampleEntity();
307+
sampleEntity.setId(documentId);
308+
sampleEntity.setMessage("hello world.");
309+
sampleEntity.setVersion(System.currentTimeMillis());
310+
repository.save(sampleEntity);
311+
// when
312+
long result = repository.deleteById(documentId);
313+
// then
314+
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build();
315+
Page<SampleEntity> sampleEntities = repository.search(searchQuery);
316+
assertThat(sampleEntities.getTotalElements(), equalTo(0L));
317+
assertThat(result, equalTo(1L));
318+
}
319+
320+
@Test
321+
public void shouldDeleteByMessageAndReturnList() {
322+
// given
323+
String documentId = randomNumeric(5);
324+
SampleEntity sampleEntity1 = new SampleEntity();
325+
sampleEntity1.setId(documentId);
326+
sampleEntity1.setMessage("hello world 1");
327+
sampleEntity1.setAvailable(true);
328+
sampleEntity1.setVersion(System.currentTimeMillis());
329+
330+
documentId = randomNumeric(5);
331+
SampleEntity sampleEntity2 = new SampleEntity();
332+
sampleEntity2.setId(documentId);
333+
sampleEntity2.setMessage("hello world 2");
334+
sampleEntity2.setAvailable(true);
335+
sampleEntity2.setVersion(System.currentTimeMillis());
336+
337+
documentId = randomNumeric(5);
338+
SampleEntity sampleEntity3 = new SampleEntity();
339+
sampleEntity3.setId(documentId);
340+
sampleEntity3.setMessage("hello world 3");
341+
sampleEntity3.setAvailable(false);
342+
sampleEntity3.setVersion(System.currentTimeMillis());
343+
repository.save(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
344+
// when
345+
List<SampleEntity> result = repository.deleteByAvailable(true);
346+
// then
347+
assertThat(result.size(), equalTo(2));
348+
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
349+
Page<SampleEntity> sampleEntities = repository.search(searchQuery);
350+
assertThat(sampleEntities.getTotalElements(), equalTo(1L));
351+
}
352+
353+
@Test
354+
public void shouldDeleteByListForMessage() {
355+
// given
356+
String documentId = randomNumeric(5);
357+
SampleEntity sampleEntity1 = new SampleEntity();
358+
sampleEntity1.setId(documentId);
359+
sampleEntity1.setMessage("hello world 1");
360+
sampleEntity1.setVersion(System.currentTimeMillis());
361+
362+
documentId = randomNumeric(5);
363+
SampleEntity sampleEntity2 = new SampleEntity();
364+
sampleEntity2.setId(documentId);
365+
sampleEntity2.setMessage("hello world 2");
366+
sampleEntity2.setVersion(System.currentTimeMillis());
367+
368+
documentId = randomNumeric(5);
369+
SampleEntity sampleEntity3 = new SampleEntity();
370+
sampleEntity3.setId(documentId);
371+
sampleEntity3.setMessage("hello world 3");
372+
sampleEntity3.setVersion(System.currentTimeMillis());
373+
repository.save(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
374+
// when
375+
List<SampleEntity> result = repository.deleteByMessage("hello world 3");
376+
// then
377+
assertThat(result.size(), equalTo(1));
378+
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
379+
Page<SampleEntity> sampleEntities = repository.search(searchQuery);
380+
assertThat(sampleEntities.getTotalElements(), equalTo(2L));
381+
}
382+
383+
@Test
384+
public void shouldDeleteByType() {
385+
// given
386+
String documentId = randomNumeric(5);
387+
SampleEntity sampleEntity1 = new SampleEntity();
388+
sampleEntity1.setId(documentId);
389+
sampleEntity1.setType("book");
390+
sampleEntity1.setVersion(System.currentTimeMillis());
391+
392+
documentId = randomNumeric(5);
393+
SampleEntity sampleEntity2 = new SampleEntity();
394+
sampleEntity2.setId(documentId);
395+
sampleEntity2.setType("article");
396+
sampleEntity2.setVersion(System.currentTimeMillis());
397+
398+
documentId = randomNumeric(5);
399+
SampleEntity sampleEntity3 = new SampleEntity();
400+
sampleEntity3.setId(documentId);
401+
sampleEntity3.setType("image");
402+
sampleEntity3.setVersion(System.currentTimeMillis());
403+
repository.save(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3));
404+
// when
405+
repository.deleteByType("article");
406+
// then
407+
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
408+
Page<SampleEntity> sampleEntities = repository.search(searchQuery);
409+
assertThat(sampleEntities.getTotalElements(), equalTo(2L));
410+
}
411+
412+
413+
302414
@Test
303415
public void shouldDeleteEntity() {
304416
// given

0 commit comments

Comments
 (0)