Jen-Ming Chung

Map-Reduce With MongoDB and Morphia

Just a note to record the usage of Map-Reduce with MongoDB and Morphia. Firstly, add the Morphia dependency.

1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>2.11.2</version>
</dependency>
<dependency>
    <groupId>org.mongodb.morphia</groupId>
    <artifactId>morphia</artifactId>
    <version>0.105</version>
</dependency>

The syntax of MapReduceCommand in Morphia as shown in MapReduceCommand.java:

1
2
3
4
5
6
7
8
9
10
public MapReduceCommand(
    DBCollection inputCollection,
    String map,
    String reduce,
    String outputCollection,
    OutputType type,
    DBObject query) {

    // Compiled Code    
}

Here we want to group the sales amount (i.e., subtotal) of each county and exclude the null-subtotal from collection. And without persisting outputs to the new collection. A sample code as shown in below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
    Morphia morphia = new Morphia();
    Datastore ds = morphia.createDatastore(mongo, dbName);

    String map = "function() { emit(this.buyerCounty,this.subtotal);}";
    String reduce = "function(k, v) {return Array.sum(v);}";

    DBObject query = new BasicDBObject("buyerCounty", new BasicDBObject("$ne", null));
    DBCollection collection = ds.getCollection(Order.class);
    MapReduceCommand cmd = new MapReduceCommand(
            collection,
            map,
            reduce,
            null,
            MapReduceCommand.OutputType.INLINE,
            query);
    MapReduceOutput out = collection.mapReduce(cmd);

    for (DBObject o : out.results()) {
        System.out.println(o.get("_id") + " :: " + o.get("value"));
    }
}

This is a portion of results, _id is the county and value is the sales amount of each county. :)

AMERICA :: 22700.0
南投縣 :: 178647.0
台中市 :: 960630.0
台北市 :: 2600085.0
台南市 :: 464212.0
台東縣 :: 8766.0
嘉義市 :: 7612.0
...

References

Comments