Skip to content

Commit 486a112

Browse files
rasmusfabersothawo
authored andcommitted
DATAES-647: Use terms-query instead of multiple should-queries for In and NotIn.
Original PR: spring-projects#315
1 parent 5efe47f commit 486a112

File tree

2 files changed

+79
-12
lines changed

2 files changed

+79
-12
lines changed

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.elasticsearch.index.query.QueryBuilders.*;
2020
import static org.springframework.data.elasticsearch.core.query.Criteria.*;
2121

22+
import java.util.ArrayList;
2223
import java.util.Iterator;
2324
import java.util.LinkedList;
2425
import java.util.List;
@@ -36,6 +37,7 @@
3637
* @author Mohsin Husen
3738
* @author Franck Marchand
3839
* @author Artur Konczak
40+
* @author Rasmus Faber-Espensen
3941
*/
4042
class CriteriaQueryProcessor {
4143

@@ -142,8 +144,6 @@ private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry,/* Operat
142144

143145
String searchText = StringUtils.toString(value);
144146

145-
Iterable<Object> collection = null;
146-
147147
switch (key) {
148148
case EQUALS:
149149
query = queryStringQuery(searchText).field(fieldName).defaultOperator(AND);
@@ -180,23 +180,23 @@ private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry,/* Operat
180180
query = fuzzyQuery(fieldName, searchText);
181181
break;
182182
case IN:
183-
query = boolQuery();
184-
collection = (Iterable<Object>) value;
185-
for (Object item : collection) {
186-
((BoolQueryBuilder) query).should(queryStringQuery(item.toString()).field(fieldName));
187-
}
183+
query = boolQuery().must(termsQuery(fieldName, toStringList((Iterable<Object>) value)));
188184
break;
189185
case NOT_IN:
190-
query = boolQuery();
191-
collection = (Iterable<Object>) value;
192-
for (Object item : collection) {
193-
((BoolQueryBuilder) query).mustNot(queryStringQuery(item.toString()).field(fieldName));
194-
}
186+
query = boolQuery().mustNot(termsQuery(fieldName, toStringList((Iterable<Object>) value)));
195187
break;
196188
}
197189
return query;
198190
}
199191

192+
private static List<String> toStringList(Iterable<?> iterable){
193+
List<String> list = new ArrayList<>();
194+
for (Object item : iterable) {
195+
list.add(StringUtils.toString(item));
196+
}
197+
return list;
198+
}
199+
200200
private void addBoost(QueryBuilder query, float boost) {
201201
if (Float.isNaN(boost)) {
202202
return;

src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,68 @@ public void shouldExecuteCustomMethodForNotIn() {
331331
assertThat(page.getContent().get(0).getId()).isEqualTo(documentId2);
332332
}
333333

334+
@Test // DATAES-647
335+
public void shouldHandleManyValuesQueryingIn() {
336+
337+
// given
338+
String documentId1 = randomNumeric(32);
339+
SampleEntity sampleEntity1 = new SampleEntity();
340+
sampleEntity1.setId(documentId1);
341+
sampleEntity1.setKeyword("foo");
342+
repository.save(sampleEntity1);
343+
344+
String documentId2 = randomNumeric(32);
345+
SampleEntity sampleEntity2 = new SampleEntity();
346+
sampleEntity2.setId(documentId2);
347+
sampleEntity2.setKeyword("bar");
348+
repository.save(sampleEntity2);
349+
350+
List<String> keywords = new ArrayList<>();
351+
keywords.add("foo");
352+
353+
for (int i = 0; i < 1025; i++) {
354+
keywords.add(randomNumeric(32));
355+
}
356+
357+
// when
358+
List<SampleEntity> list = repository.findByKeywordIn(keywords);
359+
360+
// then
361+
assertThat(list.size()).isEqualTo(1L);
362+
assertThat(list.get(0).getId()).isEqualTo(documentId1);
363+
}
364+
365+
@Test // DATAES-647
366+
public void shouldHandleManyValuesQueryingNotIn() {
367+
368+
// given
369+
String documentId1 = randomNumeric(32);
370+
SampleEntity sampleEntity1 = new SampleEntity();
371+
sampleEntity1.setId(documentId1);
372+
sampleEntity1.setKeyword("foo");
373+
repository.save(sampleEntity1);
374+
375+
String documentId2 = randomNumeric(32);
376+
SampleEntity sampleEntity2 = new SampleEntity();
377+
sampleEntity2.setId(documentId2);
378+
sampleEntity2.setKeyword("bar");
379+
repository.save(sampleEntity2);
380+
381+
List<String> keywords = new ArrayList<>();
382+
keywords.add("foo");
383+
384+
for (int i = 0; i < 1025; i++) {
385+
keywords.add(randomNumeric(32));
386+
}
387+
388+
// when
389+
List<SampleEntity> list = repository.findByKeywordNotIn(keywords);
390+
391+
// then
392+
assertThat(list.size()).isEqualTo(1L);
393+
assertThat(list.get(0).getId()).isEqualTo(documentId2);
394+
}
395+
334396
@Test
335397
public void shouldExecuteCustomMethodForTrue() {
336398

@@ -1296,6 +1358,7 @@ static class SampleEntity {
12961358
@Id private String id;
12971359
@Field(type = Text, store = true, fielddata = true) private String type;
12981360
@Field(type = Text, store = true, fielddata = true) private String message;
1361+
@Field(type = Keyword) private String keyword;
12991362
private int rate;
13001363
private boolean available;
13011364
private GeoPoint location;
@@ -1337,6 +1400,10 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository<Sa
13371400

13381401
Page<SampleEntity> findByIdIn(List<String> ids, Pageable pageable);
13391402

1403+
List<SampleEntity> findByKeywordIn(List<String> keywords);
1404+
1405+
List<SampleEntity> findByKeywordNotIn(List<String> keywords);
1406+
13401407
Page<SampleEntity> findByIdNotIn(List<String> ids, Pageable pageable);
13411408

13421409
Page<SampleEntity> findByAvailableTrue(Pageable pageable);

0 commit comments

Comments
 (0)