diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index 16b2af801..3085f5dc8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 the original author or authors. + * Copyright 2010-2014 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. @@ -46,6 +46,7 @@ import org.springframework.util.Assert; * * @author Oliver Gierke * @author Thomas Darimont + * @author Christoph Strobl */ class MongoQueryCreator extends AbstractQueryCreator { @@ -190,7 +191,9 @@ class MongoQueryCreator extends AbstractQueryCreator { case STARTING_WITH: case ENDING_WITH: case CONTAINING: - return addAppropriateLikeRegexTo(criteria, part, parameters.next().toString()); + return createContainingCriteria(part, property, criteria, parameters); + case NOT_CONTAINING: + return createContainingCriteria(part, property, criteria, parameters).not(); case REGEX: return criteria.regex(parameters.next().toString()); case EXISTS: @@ -284,6 +287,27 @@ class MongoQueryCreator extends AbstractQueryCreator { Arrays.asList(IgnoreCaseType.ALWAYS, IgnoreCaseType.WHEN_POSSIBLE), part.shouldIgnoreCase())); } + /** + * If the target property of the comparison is of type String, then the operator checks for match using regular + * expression. If the target property of the comparison is a {@link Collection} then the operator evaluates to true if + * it finds an exact match within any member of the {@link Collection}. + * + * @param part + * @param property + * @param criteria + * @param parameters + * @return + */ + private Criteria createContainingCriteria(Part part, MongoPersistentProperty property, Criteria criteria, + PotentiallyConvertingIterator parameters) { + + if (property.isCollectionLike()) { + return criteria.in(nextAsArray(parameters, property)); + } + + return addAppropriateLikeRegexTo(criteria, part, parameters.next().toString()); + } + /** * Creates an appropriate like-regex and appends it to the given criteria. * @@ -357,6 +381,7 @@ class MongoQueryCreator extends AbstractQueryCreator { source = source + "$"; break; case CONTAINING: + case NOT_CONTAINING: source = "*" + source + "*"; break; case SIMPLE_PROPERTY: diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java index a6e90fd05..b7181341e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java @@ -425,6 +425,47 @@ public class MongoQueryCreatorUnitTests { assertThat(query, is(query(where("firstName").regex("^dave$", "i").and("age").is(42)))); } + /** + * @see DATAMONGO-1075 + */ + @Test + public void shouldCreateInClauseWhenUsingContainsOnCollectionLikeProperty() { + + PartTree tree = new PartTree("findByEmailAddressesContaining", User.class); + MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "dave"), context); + + Query query = creator.createQuery(); + + assertThat(query, is(query(where("emailAddresses").in("dave")))); + } + + /** + * @see DATAMONGO-1075 + */ + @Test + public void shouldCreateInClauseWhenUsingNotContainsOnCollectionLikeProperty() { + + PartTree tree = new PartTree("findByEmailAddressesNotContaining", User.class); + MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "dave"), context); + + Query query = creator.createQuery(); + + assertThat(query, is(query(where("emailAddresses").not().in("dave")))); + } + + /** + * @see DATAMONGO-1075 + */ + @Test + public void shouldCreateRegexWhenUsingNotContainsOnStringProperty() { + + PartTree tree = new PartTree("findByUsernameNotContaining", User.class); + MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "thew"), context); + Query query = creator.createQuery(); + + assertThat(query, is(query(where("username").regex(".*thew.*").not()))); + } + interface PersonRepository extends Repository { List findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname); @@ -435,5 +476,7 @@ public class MongoQueryCreatorUnitTests { @Field("foo") String username; @DBRef User creator; + + List emailAddresses; } }