diff --git a/src/docbkx/reference/mongodb.xml b/src/docbkx/reference/mongodb.xml
index e3847c517..47009f622 100644
--- a/src/docbkx/reference/mongodb.xml
+++ b/src/docbkx/reference/mongodb.xml
@@ -1841,31 +1841,33 @@ GeoResults<Restaurant> = operations.geoNear(query, Restaurant.class);
Map-Reduce
- You can query MongoDB using Map-Reduce which his useful for batch processing, data aggregation, and
+ You can query MongoDB using Map-Reduce which is useful for batch processing, data aggregation, and
for when the query language doesn't fulfill your needs. Spring provides integration with MongoDB's map reduce
by providing methods on MongoOperations to simplify the creation and execution of Map-Reduce operations.
It also integrates
with Spring's Resource abstraction
abstraction. This will let you place your JavaScript files on the file system, classpath, http server or any other Spring Resource implementation and
then reference the JavaScript resources via an easy URI style syntax, e.g. 'classpath:reduce.js;.
- Externalizing JavaScript code in files is preferable to embedding them as Java strings in your code.
+ Externalizing JavaScript code in files is preferable to embedding them as Java strings in your code. You can still pass JavaScript code
+ as Java strings if you prefer.
+
+ Example Usage
To understand how to perform Map-Reduce operations an example from the book 'MongoDB - The definitive guide' is used. In this example
- we will create three documents, that have the values [a,b], [b,c], and [c,d] respectfully. The values in each document are associated with the key 'x' as shown below.
- For the example assume it is in the collection named "jmr1".
-
-{ "_id" : ObjectId("4e5ff893c0277826074ec533"), "x" : [ "a", "b" ] }
+ we will create three documents that have the values [a,b], [b,c], and [c,d] respectfully. The values in each document are associated with the key 'x' as shown below.
+ For this example assume these documents are in the collection named "jmr1".
+ { "_id" : ObjectId("4e5ff893c0277826074ec533"), "x" : [ "a", "b" ] }
{ "_id" : ObjectId("4e5ff893c0277826074ec534"), "x" : [ "b", "c" ] }
{ "_id" : ObjectId("4e5ff893c0277826074ec535"), "x" : [ "c", "d" ] }
-
+
A map function that will count the occurance of each letter in the array for each document is shown below
function () {
for (var i = 0; i < this.x.length; i++) {
emit(this.x[i], 1);
}
}
-
+
The reduce function that will sum up the occurance of each letter across all the documents is shown below
function (key, values) {
var sum = 0;
@@ -1873,7 +1875,7 @@ GeoResults<Restaurant> = operations.geoNear(query, Restaurant.class);
+
Executing this will result in a collection as shown below.
{ "_id" : "a", "value" : 1 }
@@ -1884,66 +1886,69 @@ GeoResults<Restaurant> = operations.geoNear(query, Restaurant.class);
- MapReduceResults<ValueObject> results = mongoOperations.mapReduce("jmr1", "classpath:map.js", "classpath:reduce.js", ValueObject.class);
- for (ValueObject valueObject : results) {
- System.out.println(valueObject);
- }
-
+MapReduceResults<ValueObject> results = mongoOperations.mapReduce("jmr1", "classpath:map.js", "classpath:reduce.js", ValueObject.class);
+for (ValueObject valueObject : results) {
+ System.out.println(valueObject);
+}
+
The output of the above code is
-
+
ValueObject [id=a, value=1.0]
ValueObject [id=b, value=2.0]
ValueObject [id=c, value=2.0]
ValueObject [id=d, value=1.0]
-
- The MapReduceResults class implement Iterable and provides access to the raw output, as well as timing and count statisticas. The ValueObject class is simply
+
+ The MapReduceResults class implements Iterable and provides access to the raw output, as well as timing and count statisticas. The ValueObject class is simply
public class ValueObject {
- private String id;
+ private String id;
+
+ private float value;
- public String getId() {
- return id;
- }
+ public String getId() {
+ return id;
+ }
- private float value;
+ public float getValue() {
+ return value;
+ }
- public float getValue() {
- return value;
- }
+ public void setValue(float value) {
+ this.value = value;
+ }
- public void setValue(float value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return "ValueObject [id=" + id + ", value=" + value + "]";
- }
+ @Override
+ public String toString() {
+ return "ValueObject [id=" + id + ", value=" + value + "]";
+ }
}
-
+
By default the output type of INLINE is used so you don't have to specify an output collection. To specify additional map-reduce options use an overloaded method
- that takes an additional The class MapReduceOptions argument. MapReduceOptions has a fluent API so adding additional options can be done
+ that takes an additional MapReduceOptions argument. The class MapReduceOptions has a fluent API so adding additional options can be done
in a very compact syntax. Here an example that sets the output collection to "jmr1_out". Note that setting only the output collection assumes a
default output type of REPLACE.
- MapReduceResults<ValueObject> results = mongoOperations.mapReduce("jmr1", "classpath:map.js", "classpath:reduce.js", new MapReduceOptions().outputCollection("jmr1_out"), ValueObject.class);
+MapReduceResults<ValueObject> results = mongoOperations.mapReduce("jmr1", "classpath:map.js", "classpath:reduce.js",
+ new MapReduceOptions().outputCollection("jmr1_out"), ValueObject.class);
There is also a static import import static org.springframework.data.mongodb.core.mapreduce.MapReduceOptions.options; that can be used to make the syntax slightly more compact
- MapReduceResults<ValueObject> results = mongoOperations.mapReduce("jmr1", "classpath:map.js", "classpath:reduce.js", options().outputCollection("jmr1_out"), ValueObject.class);
+MapReduceResults<ValueObject> results = mongoOperations.mapReduce("jmr1", "classpath:map.js", "classpath:reduce.js",
+ options().outputCollection("jmr1_out"), ValueObject.class);
You can also specify a query to reduce the set of data that will be used to feed into the map-reduce operation. This will remove the document that contains [a,b] from consideration for map-reduce operations.
- Query query = new Query(where("x").ne(new String[] { "a", "b" }));
- MapReduceResults<ValueObject> results = mongoOperations.mapReduce(query, "jmr1", "classpath:map.js", "classpath:reduce.js", options().outputCollection("jmr1_out"), ValueObject.class);
+Query query = new Query(where("x").ne(new String[] { "a", "b" }));
+MapReduceResults<ValueObject> results = mongoOperations.mapReduce(query, "jmr1", "classpath:map.js", "classpath:reduce.js",
+ options().outputCollection("jmr1_out"), ValueObject.class);
Note that you can specify additional limit and sort values as well on the query but not skip values.
-
+