基於MongoDB分布式儲存進行MapReduce並行查詢

來源:互聯網
上載者:User

      之前的文章中介紹了如何基於Mongodb進行關係型資料的分布式儲存,有了儲存就會牽扯到查詢。雖然用普通的方式也可以進行查詢,但今天要介紹的是如何使用MONGODB中提供的MapReduce功能進行查詢。
      有關MongoDb的MapReduce之前我寫過一篇文章 Mongodb Mapreduce 初窺,

      今天介紹如何基於sharding機制進行mapreduce查詢。在MongoDB的官方文檔中,這麼一句話:      

    Sharded Environments
      In sharded environments, data processing of map/reduce operations runs in parallel on all shards.

      
      即: map/reduce操作會並行運行在所有的shards上。
      下面我們就用之前這篇文章中白搭建的環境來構造mapreduce查詢:
      

      首先要說的是,基於sharding的mapreduce與非sharding的資料在返回結構上有一些區別,我目前注意到的主要是不支援定製式的json格式的返回資料,也就是下面方式可能會出現問題:     
     

   return { count : total };

      
      注意:上面的情況目前出現在了我的測試環境下,如:
     
         
     
     就需要改成 return count;
    
     下面是測試代碼,首先是按文章id來查詢相應數量(基於分組查詢執行個體方式):     
    

public partial class getfile : System.Web.UI.Page
    {

        public Mongo Mongo { get; set; }

        public IMongoDatabase DB
        {
            get
            {
                return this.Mongo["dnt_mongodb"];
            }
        }

        /// <summary>
        /// Sets up the test environment.  You can either override this OnInit to add custom initialization.
        /// </summary>
        public virtual void Init()
        {
            string ConnectionString = "Server=10.0.4.85:27017;ConnectTimeout=30000;ConnectionLifetime=300000;MinimumPoolSize=512;MaximumPoolSize=51200;Pooled=true";
            if (String.IsNullOrEmpty(ConnectionString))
                throw new ArgumentNullException("Connection string not found.");
            this.Mongo = new Mongo(ConnectionString);
            this.Mongo.Connect();         
        }
        string mapfunction = "function(){\n" +
                        "  if(this._id=='548111') { emit(this._id, 1); } \n" +   
                        "};";

        string reducefunction = "function(key, current ){" +
                                "   var count = 0;" +
                                "   for(var i in current) {" +
                                "       count+=current[i];" +
                                "   }" +
                                "   return count ;\n" +
                              "};";

      
        protected void Page_Load(object sender, EventArgs e)
        {
            Init();

            var mrb = DB["posts1"].MapReduce();//attach_gfstream.files
            int groupCount = 0;
            using (var mr = mrb.Map(mapfunction).Reduce(reducefunction))
            {
                foreach (Document doc in mr.Documents)
                {
                    groupCount = int.Parse(doc["value"].ToString());
                }
            }
            this.Mongo.Disconnect();
        }     
     }

 

     
     下面是運行時的查詢結果,如下:
     
          
     
     
     接著示範一下如何把查詢到的文章資訊返回並裝入list集合,這裡只查詢ID為548110和548111兩個文章:     
        

        string mapfunction = "function(){\n" +
                        "  if(this._id=='548110'|| this._id=='548111') { emit(this, 1); } \n" +    
                        "};";

        string reducefunction = "function(doc, current ){" +
                                "   return doc;\n" +
                               "};";
      
        protected void Page_Load(object sender, EventArgs e)
        {
            Init();

            var mrb = DB["posts1"].MapReduce();//attach_gfstream.files
            List<Document> postDoc = new List<Document>();
            using (var mr = mrb.Map(mapfunction).Reduce(reducefunction))
            {
                foreach (Document doc in mr.Documents)
                {
                    postDoc.Add((Document)doc["value"]);
                }
            }
            this.Mongo.Disconnect();
        }

 

     
     下面是運行時的查詢結果,如下:
     
         
    

     上面的map/reduce方法還有許多寫法,如果大家感興趣可以看一下如下這些連結:     
     http://cookbook.mongodb.org/patterns/unique_items_map_reduce/
     http://www.mongodb.org/display/DOCS/MapReduce
    
     以及之前我寫的這篇文章:http://www.cnblogs.com/daizhj/archive/2010/06/10/1755761.html
    
    
     當然在mongos進行map/reduce運算時,會產生一些臨時檔案,如:
  
     
     我猜這些臨時檔案可能會對重新查詢系統時的效能有一些提升(但目前未觀察到)。
    
     當然對於mongodb的gridfs系統(可使用它搭建分布式檔案儲存體系統,我之前在這篇文章中已介紹過,我也做了測試,但遺憾的是並未成功,它經常會報一些錯誤,比如:     
    

 

 

   Thu Sep 09 12:09:29   Assertion failure _grab client\parallel.cpp 461 

 

         
     看來mapreduce程式連結到mongodb上時,會產生一些問題,但不知道是不是其自身穩定性的原因,還是我的機器環境設定問題(記憶體或配置的64位系統mongos與32位的client串連問題)。
    
     好了,今天的文章就先到這裡了。   

     原文連結:http://www.cnblogs.com/daizhj/archive/2010/09/09/1822264.html

     BLOG: http://daizhj.cnblogs.com/

     作者:daizhj,代震軍

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.