DATAMONGO-701 - Improve performance of starts-with and ends-with queries.

This changes the starts-with regex to the prefixed form using ^ to better make use of any index on the queried field. Also changes ending-with queries to use the $ anchor.
This commit is contained in:
Andrew Duncan
2013-06-25 18:02:15 +02:00
committed by Oliver Gierke
parent 607072c0d3
commit 303a057d86
4 changed files with 41 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 the original author or authors.
* Copyright 2010-2013 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.
@@ -268,15 +268,16 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
private String toLikeRegex(String source, Type type) {
switch (type) {
case STARTING_WITH:
source = source + "*";
break;
case ENDING_WITH:
source = "*" + source;
break;
case CONTAINING:
source = "*" + source + "*";
break;
case STARTING_WITH:
source = "^" + source;
break;
case ENDING_WITH:
source = source + "$";
break;
case CONTAINING:
source = "*" + source + "*";
break;
default:
}
return source.replaceAll("\\*", ".*");

View File

@@ -53,11 +53,9 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
public abstract class AbstractPersonRepositoryIntegrationTests {
@Autowired
protected PersonRepository repository;
@Autowired protected PersonRepository repository;
@Autowired
MongoOperations operations;
@Autowired MongoOperations operations;
Person dave, oliver, carter, boyd, stefan, leroi, alicia;
QPerson person;
@@ -546,4 +544,26 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
assertThat(result, hasSize(1));
assertThat(result, hasItem(dave));
}
/**
* @see DATAMONGO-701
*/
@Test
public void executesDerivedStartsWithQueryCorrectly() {
List<Person> result = repository.findByLastnameStartsWith("Matt");
assertThat(result, hasSize(2));
assertThat(result, hasItems(dave, oliver));
}
/**
* @see DATAMONGO-701
*/
@Test
public void executesDerivedEndsWithQueryCorrectly() {
List<Person> result = repository.findByLastnameEndsWith("thews");
assertThat(result, hasSize(2));
assertThat(result, hasItems(dave, oliver));
}
}

View File

@@ -47,6 +47,10 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
*/
List<Person> findByLastname(String lastname);
List<Person> findByLastnameStartsWith(String prefix);
List<Person> findByLastnameEndsWith(String postfix);
/**
* Returns all {@link Person}s with the given lastname ordered by their firstname.
*

View File

@@ -263,7 +263,7 @@ public class MongoQueryCreatorUnitTests {
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "Matt"), context);
Query query = creator.createQuery();
assertThat(query, is(query(where("foo").regex("Matt.*"))));
assertThat(query, is(query(where("foo").regex("^Matt"))));
}
/**
@@ -276,7 +276,7 @@ public class MongoQueryCreatorUnitTests {
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "ews"), context);
Query query = creator.createQuery();
assertThat(query, is(query(where("foo").regex(".*ews"))));
assertThat(query, is(query(where("foo").regex("ews$"))));
}
/**