mongodb复杂查询

来源:互联网 发布:算法工程师主要做什么 编辑:程序博客网 时间:2024/06/05 21:09

mongodb复杂查询(基于mapreduce)http://blog.jobbole.com/80619/

最近想用mongodb实现一个类似于sql(select sum(xx) from table group by xxx)的东西。上数据:

phone content size 12345678901 测试12 2 12345678901 测试 1 12345678902 测试123 3 12345678902 测试1 2 12345678902 测试2 2 12345678902 测试 1 12345678902 测试 1 12345678903 测试 1


sql语句

 select sum(size) from table_name group by phone 

js(mapreduce)注:reduce函数返回结果数据结构必须和map函数value的数据结构一致。因为reduce函数会将自己的返回值再次作为下一次reduce的输入值使用。

map:    function() {            ###total:自定义(作为json的key)            emit(phone,{total:this.size});        }reduce:    function(key,values) {            var sum = {total:0};            for (var i=0;i<values.length;i++){                  ###sum.total相当于total对应的值(size)                                         sum.total +=  values[i].total;             }            ###sum的数据结构必须和map函数的value的结构一致                return sum;        }

spring-mongodb实现(mapreduce)

 <mongo:mongo id="mongo" host="${db.mongoAddress}" port="${db.mongoPort}"/>    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">        <constructor-arg ref="mongo"/>        <constructor-arg name="databaseName" value="${db.mongoName}"/>        <constructor-arg name="userCredentials" ref="userCredentials"/>    </bean>    <bean id="userCredentials" class="org.springframework.data.authentication.UserCredentials">        <constructor-arg name="username" value="${db.mongoUsername}"/>        <constructor-arg name="password" value="${db.mongoPassword}"/>    </bean>
//map函数String m ="function() {"+            "emit(phone,{total:this.size});"+        "}";//reduce函数        String r = "function(key,values) {"+                "var sum = {total:0};"+                "for (var i=0;i<values.length;i++){" +                "sum.total += values[i].total;" +                "}"+                "return sum;"+                "}";        MapReduceResults persons = mongoTemplate.mapReduce("connection_", m, r, null);        BasicDBList list = (BasicDBList) persons.getRawResults().get("results");        for (int i = 0; i < list.size(); i ++) {            BasicDBObject obj = (BasicDBObject)list.get(i);            Object o = obj.get("value");          System.out.println(JSON.toJSONString(obj));        }

测试结果

phone size 12345678901 3 12345678902 9 12345678903 1
0 0