diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java index 966835448..bdc4787ba 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java @@ -26,6 +26,8 @@ import org.springframework.data.document.InvalidDocumentStoreApiUsageException; public class Criteria implements CriteriaDefinition { private String key; + + private List criteriaChain; private LinkedHashMap criteria = new LinkedHashMap(); @@ -33,9 +35,16 @@ public class Criteria implements CriteriaDefinition { public Criteria(String key) { + this.criteriaChain = new ArrayList(); + this.criteriaChain.add(this); this.key = key; } + protected Criteria(List criteriaChain, String key) { + this.criteriaChain = criteriaChain; + this.criteriaChain.add(this); + this.key = key; + } /** * Static factory method to create a Criteria using the provided key @@ -47,6 +56,16 @@ public class Criteria implements CriteriaDefinition { return new Criteria(key); } + /** + * Static factory method to create a Criteria using the provided key + * + * @param key + * @return + */ + public Criteria and(String key) { + return new Criteria(this.criteriaChain, key); + } + /** * Creates a criterion using the $is operator * @@ -207,6 +226,16 @@ public class Criteria implements CriteriaDefinition { return this; } + /** + * Creates a criterion using the $elemMatch operator + * + * @param t + * @return + */ + public Criteria elemMatch(Criteria c) { + criteria.put("$elemMatch", c.getCriteriaObject()); + return this; + } /** * Creates an or query using the $or operator for all of the provided queries * @@ -224,6 +253,19 @@ public class Criteria implements CriteriaDefinition { * @see org.springframework.datastore.document.mongodb.query.Criteria#getCriteriaObject(java.lang.String) */ public DBObject getCriteriaObject() { + if (this.criteriaChain.size() == 1) { + return criteriaChain.get(0).getSingleCriteriaObject(); + } + else { + DBObject criteriaObject = new BasicDBObject(); + for (Criteria c : this.criteriaChain) { + criteriaObject.putAll(c.getSingleCriteriaObject()); + } + return criteriaObject; + } + } + + protected DBObject getSingleCriteriaObject() { DBObject dbo = new BasicDBObject(); boolean not = false; for (String k : this.criteria.keySet()) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/CriteriaTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/CriteriaTests.java new file mode 100644 index 000000000..2d83943aa --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/CriteriaTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2011 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.document.mongodb.query; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.data.document.mongodb.query.Index.Duplicates; + +public class CriteriaTests { + + @Test + public void testSimpleCriteria() { + Criteria c = new Criteria("name").is("Bubba"); + Assert.assertEquals("{ \"name\" : \"Bubba\"}", c.getCriteriaObject().toString()); + } + + @Test + public void testChainedCriteria() { + Criteria c = new Criteria("name").is("Bubba").and("age").lt(21); + Assert.assertEquals("{ \"name\" : \"Bubba\" , \"age\" : { \"$lt\" : 21}}", c.getCriteriaObject().toString()); + } +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/QueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/QueryTests.java index df6de21a4..76426e4b8 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/QueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/query/QueryTests.java @@ -29,6 +29,13 @@ public class QueryTests { Assert.assertEquals(expected, q.getQueryObject().toString()); } + @Test + public void testSimpleQueryWithChainedCriteria() { + Query q = new Query(where("name").is("Thomas").and("age").lt(80)); + String expected = "{ \"name\" : \"Thomas\" , \"age\" : { \"$lt\" : 80}}"; + Assert.assertEquals(expected, q.getQueryObject().toString()); + } + @Test public void testQueryWithNot() { Query q = new Query(where("name").is("Thomas")).and(where("age").not().mod(10, 0)); @@ -74,4 +81,10 @@ public class QueryTests { Assert.assertEquals(expected, q.getQueryObject().toString()); } + @Test + public void testQueryWithElemMatch() { + Query q = new Query(where("openingHours").elemMatch(where("dayOfWeek").is("Monday").and("open").lte("1800"))); + String expected = "{ \"openingHours\" : { \"$elemMatch\" : { \"dayOfWeek\" : \"Monday\" , \"open\" : { \"$lte\" : \"1800\"}}}}"; + Assert.assertEquals(expected, q.getQueryObject().toString()); + } }