在mongodb中使用mapreduce统计

在mongodb中一般的统计使用group就够了,但是针对大数据量group远远不够,这时使用自带的mapreduce统计不失为一个
好方法。当然也可以配置hadoop,结合hadoop使用更好。
mongodb中主要使用集合中的mapReduce方法来调用用js函数编写好的Map和reduce。

对于程序来说这里主要就是JS的编写了。既可以直接如下嵌入到代码中也可以把单独的js函数拿出来,再在java代码中加载

 @Test
    public void testMapReduce(){//插入测试数据
      
    Mongo  _db = new Mongo( "127.0.0.1" ).getDB( "jmrtest" ); 

    DBCollection c = _db.getCollection( "jmr" );
        c.drop();

        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" } ) );
        
        MapReduceOutput out =
            c.mapReduce( "function(){ " +
            		"for( var i=0; i<this.x.length; i++ )" +
            		"{ emit(this.x[i] , 1 ); } }",//map函数内使用this来操作当前行表示的对象,并且使用emit(key,value)方法来向reduce提供参数:
            		"function(key,values){" +
            		" var sum=0; " +
            		"for( var i=0; i<values.length; i++ )" +
            		" sum += values[i];" +
            		" return sum;}" ,//reduce的key就是emit(key,value)的key,value_array是同个key对应的多个value数组:
                         "result" , null );//mapReduce 方法2.x以后和1.X不同
        
        Map<String,Integer> m = new HashMap<String,Integer>();
        for (DBObject element :  out.results()) {
        	 System.out.println(element.get("value"));
		}
        for ( DBObject r : out.results() ){
        	System.out.println( ((Number)(r.get( "value" ))).intValue());
            m.put( r.get( "_id" ).toString() , ((Number)(r.get( "value" ))).intValue() );
        }
        System.out.println(m.size());
        assertEquals( 4 , m.size() );
        assertEquals( 1 , m.get( "a" ).intValue() );
        assertEquals( 2 , m.get( "b" ).intValue() );
        assertEquals( 2 , m.get( "c" ).intValue() );
        assertEquals( 1 , m.get( "d" ).intValue() );
                        
    }
 

相关推荐