DATAMONGO-652 - Added support for $elemMatch and $ positional operator.

This commit is contained in:
Patryk Wąsik
2013-04-12 14:26:24 +02:00
committed by Oliver Gierke
parent 071cd1647f
commit 9d83331f9f
2 changed files with 69 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 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.
@@ -17,15 +17,25 @@ package org.springframework.data.mongodb.core.query;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* @author Thomas Risberg
* @author Oliver Gierke
* @author Patryk Wasik
*/
public class Field {
private Map<String, Integer> criteria = new HashMap<String, Integer>();
private Map<String, Object> slices = new HashMap<String, Object>();
private final Map<String, Integer> criteria = new HashMap<String, Integer>();
private final Map<String, Object> slices = new HashMap<String, Object>();
private final Map<String, Criteria> elemMatchs = new HashMap<String, Criteria>();
private String postionKey;
private int positionValue;
public Field include(String key) {
criteria.put(key, Integer.valueOf(1));
@@ -47,14 +57,50 @@ public class Field {
return this;
}
public Field elemMatch(String key, Criteria elemMatchCriteria) {
elemMatchs.put(key, elemMatchCriteria);
return this;
}
/**
* The array field must appear in the query. Only one positional {@code $} operator can appear in the projection and
* only one array field can appear in the query.
*
* @param field query array field, must not be {@literal null} or empty.
* @param value
* @return
*/
public Field position(String field, int value) {
Assert.hasText(field, "Field must not be null or empty!");
postionKey = field;
positionValue = value;
return this;
}
public DBObject getFieldsObject() {
DBObject dbo = new BasicDBObject();
for (String k : criteria.keySet()) {
dbo.put(k, (criteria.get(k)));
dbo.put(k, criteria.get(k));
}
for (String k : slices.keySet()) {
dbo.put(k, new BasicDBObject("$slice", (slices.get(k))));
dbo.put(k, new BasicDBObject("$slice", slices.get(k)));
}
for (Entry<String, Criteria> entry : elemMatchs.entrySet()) {
DBObject dbObject = new BasicDBObject("$elemMatch", entry.getValue().getCriteriaObject());
dbo.put(entry.getKey(), dbObject);
}
if (postionKey != null) {
dbo.put(postionKey + ".$", positionValue);
}
return dbo;
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.query;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import org.junit.Assert;
import org.junit.Rule;
@@ -32,6 +33,7 @@ import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
*
* @author Thomas Risberg
* @author Oliver Gierke
* @author Patryk Wasik
*/
public class QueryTests {
@@ -104,6 +106,21 @@ public class QueryTests {
Assert.assertEquals(expectedFields, q.getFieldsObject().toString());
}
/**
* @see DATAMONGO-652
*/
@Test
public void testQueryWithFieldsElemMatchAndPositionalOperator() {
Query query = query(where("name").gte("M").lte("T").and("age").not().gt(22));
query.fields().elemMatch("products", where("name").is("milk")).position("comments", 2);
String expected = "{ \"name\" : { \"$gte\" : \"M\" , \"$lte\" : \"T\"} , \"age\" : { \"$not\" : { \"$gt\" : 22}}}";
assertThat(query.getQueryObject().toString(), is(expected));
String expectedFields = "{ \"products\" : { \"$elemMatch\" : { \"name\" : \"milk\"}} , \"comments.$\" : 2}";
assertThat(query.getFieldsObject().toString(), is(expectedFields));
}
@Test
public void testSimpleQueryWithChainedCriteria() {
Query q = new Query(where("name").is("Thomas").and("age").lt(80));