• MongoDb mapreduce


           周四脑袋发热,突然想获取文档中id的最大值,发现mongodb中没有sql中max聚合函数,只能通过对整个文档使用sort和limit(1)获取最大值。感觉很不

    爽,突然想起map-reduce不就是聚合用的吗,于是乎就写了这个map-reduce的聚合功能。我的js一般,mongodb初学,很多东西没弄明白,我将实现方式和疑问在这里记录下来,

    意识要和大家分享下,一是避免初学者和我犯同样的错误,而是希望有人解答我的疑问。

    我在这里利用map-reduce主要实现了 max 和 sum 功能,其他功能的实现类似。直接上代码了

    using MongoDB.Bson;
    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace Mongo.Util
    {
        public static class Extension
        {
            /// <summary>
            /// 获取集合文档数量
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="collection"></param>
            /// <returns></returns>
            public static Dictionary<string, int> CountKeyOfCollection<T>(this MongoCollection<T> collection)
            {
                var map = @"function() {" +
          "    for (var key in this) {" +
          "        emit(key, { count : 1 });" +
          "    }" +
          "}";
    
                var reduce = @"function(key, emits) {" +
                    "    total = 0;" +
                    "    for (var i in emits) {" +
                    "        total += emits[i].count;" +
                    "    }" +
                    "    return { count : total };" +
                    "}";
                var finalize = @"";
                var mra = new MapReduceArgs();
                mra.MapFunction = map;
                mra.ReduceFunction = reduce;
                var mr = collection.MapReduce(mra);
                Dictionary<string, int> dict = new Dictionary<string, int>();
                foreach (var document in mr.GetResults())
                {
                    var json = document.ToJson();
                    JObject obj = JsonConvert.DeserializeObject<JObject>(json);
                    var _id = obj["_id"];
                    var count = obj["value"]["count"];
                    dict.Add(_id.ToString(), Convert.ToInt32(count));
                }
                return dict;
    
            }
    
            /// <summary>
            /// 这个错误,怎么获取当前key 的value
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="collection"></param>
            public static void Max<T>(this MongoCollection<T> collection)
            {
                //怎么获取当前key 的value
                var map = @"function(){
                                  for(var key in this){
                                         emit(key,value);
                                }                
                            }";
                var reduce = @"function(key,values){
                    var max=values[0];
                     var tmp;
                        for(var i =1;i<values.lenght;i++)
                        {
                            tmp=values[i];
                            if(max<tmp)
                                 max=tmp;
                        }
                      return max;
                    }";
                var finalize = "";
                var mra = new MapReduceArgs();
                mra.MapFunction = map;
                mra.ReduceFunction = reduce;
                var mr = collection.MapReduce(mra);
            }
            /// <summary>
            /// 对指定key 求 max
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="collection"></param>
            /// <param name="field">key大小写敏感</param>
            public static void Max<T>(this MongoCollection<T> collection, string field)
            {
                var map = "function(){ "
                                + "for(var key1 in this) "
                                 + "                  { "
                                 + "                    if(key1.toLowerCase()=='"+field.ToLower()+"')"
                                 + "                           {"
                                 + "                              emit(key1,this."+field+");"
                                + "                           }"
                                + "             }"
                                 + "                   }";
    
                var reduce = @"function(key,values){
                                var maxTmp=values[0];
                                 for(var i=1;i<values.length;i++)
                                {
                                    if(maxTmp<values[i])
                                        maxTmp=values[i];
                               }
                            return {key:key,max:maxTmp};
                    }";
                var finalize = "";
                var mra = new MapReduceArgs();
                mra.MapFunction = map;
                mra.ReduceFunction = reduce;
                var mr = collection.MapReduce(mra);
            }
            /// <summary>
            /// 对指定key求和
            /// 
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="collection"></param>
            /// <param name="field">key大小写敏感</param>
            public static void Sum<T>(this MongoCollection<T> collection, string field)
            {
                var map = "function(){ "
                                + "for(var key1 in this) "
                                 + "                  { "
                                 + "                    if(key1.toLowerCase()=='" + field.ToLower() + "')"
                                 + "                           {"
                                 + "                              emit(key1,this." + field + ");"
                                + "                           }"
                                + "             }"
                                 + "                   }";
    
                var reduce = @"function(key,values){
                             var ret= {key:key,sum:values.reduce(function(prev, cur, index, array){return prev + cur;})};    
                            return ret;
                    }";
                var finalize = "";
                var mra = new MapReduceArgs();
                mra.MapFunction = map;
                mra.ReduceFunction = reduce;
                var mr = collection.MapReduce(mra);
            }
    
            /// <summary>
            /// 对指定key求和
            /// 怎么判断value类型 $type=2 js判断方法
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="collection"></param>
            /// <param name="field">key大小写敏感</param>
            public static void Sum2<T>(this MongoCollection<T> collection, string field)
            {
                var map = "function(){ "
                                + "for(var key1 in this) "
                                 + "                  { "
                                 + "                    if(key1.toLowerCase()=='" + field.ToLower() + "')"
                                 + "                           {"
                                 + "                              emit(key1,this." + field + ");"
                                + "                           }"
                                + "             }"
                                 + "                   }";
    
                var reduce = @"function(key,values){
                             var ret= {key:key,sum:Array.sum(values)};    
                            return ret;
                    }";
                var finalize = "";
                var mra = new MapReduceArgs();
                mra.MapFunction = map;
                mra.ReduceFunction = reduce;
                var mr = collection.MapReduce(mra);
            }
    
            /// <summary>
            /// 这个错误,到底this 能获取什么 key value ????
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="collection"></param>
            public static void Sum<T>(this MongoCollection<T> collection)
            {
                //关键问题怎么获取当前key 对应的value 怎么解决
                var map = "function(){ "
                                +"var i=0;"
                                 + "for(var key1 in this) "
                                  + "                  { "
                                  + "                              emit(key1,value[i]);" 
                                  +"i++;"
                                 + "             }"
                                  + " }";
    
                var reduce = @"function(key,values){
                             var ret= {key:key,sum:values.reduce(function(prev, cur, index, array){return prev + cur;})};    
                            return ret;
                    }";
                var finalize = "";
                var mra = new MapReduceArgs();
                mra.MapFunction = map;
                mra.ReduceFunction = reduce;
                var mr = collection.MapReduce(mra);
            }
    
    
        }
    }

    注意:上边我说明错误的方法,是我希望高手指点的,这里只有max和sum方法能用,不要怀疑我的能力哦。

    我想请教大家,map reduce中的this 到底是什么东东,当前文档,有什么属性可以使用, 我怎么看着当前key对应的value

    参考学习资料:http://www.cnblogs.com/loogn/archive/2012/02/09/2344054.html

      http://docs.mongodb.org/manual/reference/command/mapReduce/

  • 相关阅读:
    CMS .NET 程序框架 从2.0/3.5升级到4.0 版本后 需要调整的地方
    配置信息
    修改SQL Server 2005 数据库文件名字
    生成一行html
    安卓模拟器研究-root
    Win8.1屏幕亮度自动调节关闭方法
    ORA-01012:not logged on的解决办法
    ORA-00845: MEMORY_TARGET not supported on this system
    Linux vmstat命令实战详解
    Linux操作系统下Oracle主要监控工具介绍
  • 原文地址:https://www.cnblogs.com/xiyoujiyjy/p/4355414.html
Copyright © 2020-2023  润新知