DATAMONGO-1424 - Add support for NOT_LIKE.

We now support `notLike` and `isNotLike` in query derivation.

Original pull request: #364.
This commit is contained in:
Christoph Strobl
2016-04-26 14:16:40 +02:00
committed by Mark Paluch
parent e03520d2fb
commit 2f713bede5
6 changed files with 85 additions and 4 deletions

View File

@@ -72,7 +72,7 @@ public enum MongoRegexCreator {
return source;
}
if (!ObjectUtils.nullSafeEquals(Type.LIKE, type)) {
if (!ObjectUtils.nullSafeEquals(Type.LIKE, type) && !ObjectUtils.nullSafeEquals(Type.NOT_LIKE, type)) {
return PUNCTATION_PATTERN.matcher(source).find() ? Pattern.quote(source) : source;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2016 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.
@@ -199,6 +199,8 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
case ENDING_WITH:
case CONTAINING:
return createContainingCriteria(part, property, criteria, parameters);
case NOT_LIKE:
return createContainingCriteria(part, property, criteria.not(), parameters);
case NOT_CONTAINING:
return createContainingCriteria(part, property, criteria.not(), parameters);
case REGEX:

View File

@@ -1296,4 +1296,15 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
assertThat(result, not(hasItem(carter)));
}
/*
* @see DATAMONGO-1424
*/
@Test
public void findsPersonsByFirstnameNotLike() throws Exception {
List<Person> result = repository.findByFirstnameNotLike("Bo*");
assertThat(result.size(), is((int) (repository.count() - 1)));
assertThat(result, not(hasItem(boyd)));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2016 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.
@@ -91,6 +91,14 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
List<Person> findByFirstnameNotContains(String firstname);
/**
* Returns all {@link Person}s with a firstname not matching the given one (*-wildcard supported).
*
* @param firstname
* @return
*/
List<Person> findByFirstnameNotLike(String firstname);
List<Person> findByFirstnameLikeOrderByLastnameAsc(String firstname, Sort sort);
List<Person> findBySkillsContains(List<String> skills);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2016 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.
@@ -669,6 +669,62 @@ public class MongoQueryCreatorUnitTests {
assertThat(query, is(query(where("emailAddresses").in((Object) null))));
}
/**
* @see DATAMONGO-1424
*/
@Test
public void notLikeShouldEscapeSourceWhenUsedWithLeadingAndTrailingWildcard() {
PartTree tree = new PartTree("findByUsernameNotLike", User.class);
ConvertingParameterAccessor accessor = getAccessor(converter, "*fire.fight+*");
Query query = new MongoQueryCreator(tree, accessor, context).createQuery();
assertThat(query.getQueryObject(),
is(query(where("username").not().regex(".*\\Qfire.fight+\\E.*")).getQueryObject()));
}
/**
* @see DATAMONGO-1424
*/
@Test
public void notLikeShouldEscapeSourceWhenUsedWithLeadingWildcard() {
PartTree tree = new PartTree("findByUsernameNotLike", User.class);
ConvertingParameterAccessor accessor = getAccessor(converter, "*steel.heart+");
Query query = new MongoQueryCreator(tree, accessor, context).createQuery();
assertThat(query.getQueryObject(),
is(query(where("username").not().regex(".*\\Qsteel.heart+\\E")).getQueryObject()));
}
/**
* @see DATAMONGO-1424
*/
@Test
public void notLikeShouldEscapeSourceWhenUsedWithTrailingWildcard() {
PartTree tree = new PartTree("findByUsernameNotLike", User.class);
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "cala.mity+*"), context);
Query query = creator.createQuery();
assertThat(query.getQueryObject(), is(query(where("username").not().regex("\\Qcala.mity+\\E.*")).getQueryObject()));
}
/**
* @see DATAMONGO-1424
*/
@Test
public void notLikeShouldBeTreatedCorrectlyWhenUsedWithWildcardOnly() {
PartTree tree = new PartTree("findByUsernameNotLike", User.class);
ConvertingParameterAccessor accessor = getAccessor(converter, "*");
Query query = new MongoQueryCreator(tree, accessor, context).createQuery();
assertThat(query.getQueryObject(), is(query(where("username").not().regex(".*")).getQueryObject()));
}
interface PersonRepository extends Repository<Person, Long> {
List<Person> findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname);

View File

@@ -208,6 +208,10 @@ NOTE: Note that for version 1.0 we currently don't support referring to paramete
| `findByFirstnameLike(String name)`
| `{"firstname" : name} ( name as regex)`
| `NotLike`, `IsNotLike`, `EndingWith`
| `findByFirstnameNotLike(String name)`
| `{"firstname" : { "$not" : name }} ( name as regex)`
| `Containing` on String
| `findByFirstnameContaining(String name)`
| `{"firstname" : name} (name as regex)`