DATADOC-7 - Support for map-reduce operations in MongoTemplate
This commit is contained in:
@@ -270,48 +270,52 @@ public interface MongoOperations {
|
||||
|
||||
/**
|
||||
* Execute a map-reduce operation. The map-reduce operation will be formed with an output type of INLINE
|
||||
* @param inputCollectionName the collection where the map-reduce will read from
|
||||
* @param mapFunction The JavaScript map function
|
||||
* @param reduceFunction The JavaScript reduce function
|
||||
* @param mapReduceOptions Options that specify detailed map-reduce behavior
|
||||
* @param entityClass The parameterized type of the returned list
|
||||
* @return The results of the map reduce operation
|
||||
*/
|
||||
<T> MapReduceResults<T> mapReduce(String mapFunction, String reduceFunction, Class<T> entityClass );
|
||||
<T> MapReduceResults<T> mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, Class<T> entityClass );
|
||||
|
||||
|
||||
/**
|
||||
* Execute a map-reduce operation that takes additional map-reduce options.
|
||||
* @param inputCollectionName the collection where the map-reduce will read from
|
||||
* @param mapFunction The JavaScript map function
|
||||
* @param reduceFunction The JavaScript reduce function
|
||||
* @param mapReduceOptions Options that specify detailed map-reduce behavior
|
||||
* @param entityClass The parameterized type of the returned list
|
||||
* @return The results of the map reduce operation
|
||||
*/
|
||||
<T> MapReduceResults<T> mapReduce(String mapFunction, String reduceFunction, MapReduceOptions mapReduceOptions, Class<T> entityClass );
|
||||
<T> MapReduceResults<T> mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, MapReduceOptions mapReduceOptions, Class<T> entityClass );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute a map-reduce operation that takes a query. The map-reduce operation will be formed with an output type of INLINE
|
||||
* @param query The query to use to select the data for the map phase
|
||||
* @param inputCollectionName the collection where the map-reduce will read from
|
||||
* @param mapFunction The JavaScript map function
|
||||
* @param reduceFunction The JavaScript reduce function
|
||||
* @param mapReduceOptions Options that specify detailed map-reduce behavior
|
||||
* @param entityClass The parameterized type of the returned list
|
||||
* @return The results of the map reduce operation
|
||||
*/
|
||||
<T> MapReduceResults<T> mapReduce(Query query, String mapFunction, String reduceFunction, Class<T> entityClass );
|
||||
<T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, Class<T> entityClass );
|
||||
|
||||
/**
|
||||
* Execute a map-reduce operation that takes a query and additional map-reduce options
|
||||
* @param query The query to use to select the data for the map phase
|
||||
* @param inputCollectionName the collection where the map-reduce will read from
|
||||
* @param mapFunction The JavaScript map function
|
||||
* @param reduceFunction The JavaScript reduce function
|
||||
* @param mapReduceOptions Options that specify detailed map-reduce behavior
|
||||
* @param entityClass The parameterized type of the returned list
|
||||
* @return The results of the map reduce operation
|
||||
*/
|
||||
<T> MapReduceResults<T> mapReduce(Query query, String mapFunction, String reduceFunction, MapReduceOptions mapReduceOptions, Class<T> entityClass );
|
||||
<T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, MapReduceOptions mapReduceOptions, Class<T> entityClass );
|
||||
|
||||
/**
|
||||
* Returns {@link GeoResult} for all entities matching the given {@link NearQuery}. Will consider entity mapping
|
||||
|
||||
@@ -832,24 +832,24 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
entityClass), collectionName);
|
||||
}
|
||||
|
||||
public <T> MapReduceResults<T> mapReduce(String mapFunction, String reduceFunction, Class<T> entityClass) {
|
||||
return mapReduce(null, mapFunction, reduceFunction, new MapReduceOptions().outputTypeInline(), entityClass);
|
||||
public <T> MapReduceResults<T> mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, Class<T> entityClass) {
|
||||
return mapReduce(null, inputCollectionName, mapFunction, reduceFunction, new MapReduceOptions().outputTypeInline(), entityClass);
|
||||
}
|
||||
|
||||
public <T> MapReduceResults<T> mapReduce(String mapFunction, String reduceFunction,
|
||||
public <T> MapReduceResults<T> mapReduce(String inputCollectionName, String mapFunction, String reduceFunction,
|
||||
MapReduceOptions mapReduceOptions, Class<T> entityClass) {
|
||||
return mapReduce(null, mapFunction, reduceFunction, mapReduceOptions, entityClass);
|
||||
return mapReduce(null, inputCollectionName, mapFunction, reduceFunction, mapReduceOptions, entityClass);
|
||||
}
|
||||
|
||||
public <T> MapReduceResults<T> mapReduce(Query query, String mapFunction, String reduceFunction, Class<T> entityClass) {
|
||||
return mapReduce(query, mapFunction, reduceFunction, new MapReduceOptions().outputTypeInline(), entityClass);
|
||||
public <T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, Class<T> entityClass) {
|
||||
return mapReduce(query, inputCollectionName, mapFunction, reduceFunction, new MapReduceOptions().outputTypeInline(), entityClass);
|
||||
}
|
||||
|
||||
public <T> MapReduceResults<T> mapReduce(Query query, String mapFunction, String reduceFunction,
|
||||
public <T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction,
|
||||
MapReduceOptions mapReduceOptions, Class<T> entityClass) {
|
||||
String mapFunc = replaceWithResourceIfNecessary(mapFunction);
|
||||
String reduceFunc = replaceWithResourceIfNecessary(reduceFunction);
|
||||
DBCollection inputCollection = getCollection(this.determineCollectionName(entityClass));
|
||||
DBCollection inputCollection = getCollection(inputCollectionName);
|
||||
MapReduceCommand command = new MapReduceCommand(inputCollection, mapFunc, reduceFunc,
|
||||
mapReduceOptions.getOutputCollection(), mapReduceOptions.getOutputType(), null);
|
||||
|
||||
@@ -866,11 +866,18 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
} else {
|
||||
commandResult = executeCommand(commandObject);
|
||||
}
|
||||
commandResult.throwOnError();
|
||||
commandResult.throwOnError();
|
||||
} catch (RuntimeException ex) {
|
||||
this.potentiallyConvertRuntimeException(ex);
|
||||
}
|
||||
|
||||
String error = commandResult.getErrorMessage();
|
||||
if (error != null) {
|
||||
throw new InvalidDataAccessApiUsageException("Command execution failed: Error [" + error + "], Command = " + commandObject);
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MapReduce command result = [" + commandResult + "]");
|
||||
}
|
||||
MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult);
|
||||
List<T> mappedResults = new ArrayList<T>();
|
||||
DbObjectCallback<T> callback = new ReadDbObjectCallback<T>(mongoConverter, entityClass);
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -87,9 +88,18 @@ public class MapReduceTests {
|
||||
protected void cleanDb() {
|
||||
template.dropCollection(template.getCollectionName(ValueObject.class));
|
||||
template.dropCollection("jmr1_out");
|
||||
|
||||
template.dropCollection("jmr1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testForDocs() {
|
||||
createMapReduceData();
|
||||
MapReduceResults<ValueObject> results = mongoTemplate.mapReduce("jmr1", mapFunction, reduceFunction, ValueObject.class);
|
||||
for (ValueObject valueObject : results) {
|
||||
System.out.println(valueObject);
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testMapReduce() {
|
||||
performMapReduce(false, false);
|
||||
@@ -114,7 +124,7 @@ public class MapReduceTests {
|
||||
|
||||
String mapWithExcludeFunction = "function(){ for ( var i=0; i<this.x.length; i++ ){ if(this.x[i] != exclude) emit( this.x[i] , 1 ); } }";
|
||||
|
||||
MapReduceResults<ValueObject> results = mongoTemplate.mapReduce(mapWithExcludeFunction, reduceFunction,
|
||||
MapReduceResults<ValueObject> results = mongoTemplate.mapReduce("jmr1", mapWithExcludeFunction, reduceFunction,
|
||||
new MapReduceOptions().scopeVariables(scopeVariables).outputTypeInline(), ValueObject.class);
|
||||
Map<String, Float> m = copyToMap(results);
|
||||
assertEquals(3, m.size());
|
||||
@@ -128,7 +138,7 @@ public class MapReduceTests {
|
||||
createMapReduceData();
|
||||
|
||||
Query query = new Query(where("x").ne(new String[] { "a", "b" }));
|
||||
MapReduceResults<ValueObject> results = mongoTemplate.mapReduce(query, mapFunction, reduceFunction, ValueObject.class);
|
||||
MapReduceResults<ValueObject> results = mongoTemplate.mapReduce(query, "jmr1", mapFunction, reduceFunction, ValueObject.class);
|
||||
|
||||
Map<String, Float> m = copyToMap(results);
|
||||
assertEquals(3, m.size());
|
||||
@@ -144,15 +154,15 @@ public class MapReduceTests {
|
||||
MapReduceResults<ValueObject> results;
|
||||
if (inline) {
|
||||
if (withQuery) {
|
||||
results = mongoTemplate.mapReduce(new Query(), "classpath:map.js", "classpath:reduce.js", ValueObject.class);
|
||||
results = mongoTemplate.mapReduce(new Query(), "jmr1", "classpath:map.js", "classpath:reduce.js", ValueObject.class);
|
||||
} else {
|
||||
results = mongoTemplate.mapReduce(mapFunction, reduceFunction, ValueObject.class);
|
||||
results = mongoTemplate.mapReduce("jmr1", mapFunction, reduceFunction, ValueObject.class);
|
||||
}
|
||||
} else {
|
||||
if (withQuery) {
|
||||
results = mongoTemplate.mapReduce(new Query(), mapFunction, reduceFunction, options().outputCollection("jmr1_out"), ValueObject.class);
|
||||
results = mongoTemplate.mapReduce(new Query(), "jmr1", mapFunction, reduceFunction, options().outputCollection("jmr1_out"), ValueObject.class);
|
||||
} else {
|
||||
results = mongoTemplate.mapReduce(mapFunction, reduceFunction, new MapReduceOptions().outputCollection("jmr1_out"), ValueObject.class);
|
||||
results = mongoTemplate.mapReduce("jmr1", mapFunction, reduceFunction, new MapReduceOptions().outputCollection("jmr1_out"), ValueObject.class);
|
||||
}
|
||||
}
|
||||
Map<String, Float> m = copyToMap(results);
|
||||
@@ -160,7 +170,7 @@ public class MapReduceTests {
|
||||
}
|
||||
|
||||
private void createMapReduceData() {
|
||||
DBCollection c = mongoTemplate.getDb().getCollection(template.getCollectionName(ValueObject.class));
|
||||
DBCollection c = mongoTemplate.getDb().getCollection("jmr1");
|
||||
c.save(new BasicDBObject("x", new String[] { "a", "b" }));
|
||||
c.save(new BasicDBObject("x", new String[] { "b", "c" }));
|
||||
c.save(new BasicDBObject("x", new String[] { "c", "d" }));
|
||||
|
||||
@@ -22,8 +22,5 @@ public class ValueObject {
|
||||
public String toString() {
|
||||
return "ValueObject [id=" + id + ", value=" + value + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user