用MongoDB實現MapReduce

openkk 12年前發布 | 63K 次閱讀 MongoDB MapReduce NoSQL數據庫

MapReduce 是 Google 在 2004 年發布的一個軟件框架,用于支持大規模數據的分布式計算,詳情請看這里

MongoDB 是一個開源的面向文檔的 NoSQL 數據庫系統,使用 C++ 編寫,詳情請看這里

1. 安裝 MangoDB

首先請按照官方這個文檔安裝 MongoDB 數據庫,在本文中,我們是在 Mac OS X 下安裝并測試無誤。

我使用 sudo port install mongodb 命令來安裝 MongoDB ,唯一碰到的一個問題是 xcode 的版本問題,升級到 xcode 的最新版本就好了。

2. 運行 MongoDB

啟動 MongoDB 是很簡單的,只需要在終端窗口中執行 mogod 即可。

默認 MongoDB 是運行在 27017 端口上,使用 /data/db 作為默認目錄來存放數據(我們已經在第一步就創建了這個目錄)

如果你修改這些默認的配置,你可以通過命令行參數來進行修改:

mongod --port [your_port] --dbpath [your_db_file_path]

你需要確認的是數據目錄必須已經存在并且在 mongodb 首次啟動時該目錄下沒有其他文件。

3. 啟動 MongoDB 交互環境

我們可以啟動 MongoDB 交互環境來連接到 MongoDB 服務器,并在命令行中直接運行 MongoDB 命令。

在同一臺機器上,你只需要簡單的執行 mongo 就可以進入交互環境,如果想要連接不同機器上的 MongoDB 服務器,你可以使用下面的參數來指定目標服務器的IP地址和端口:

mongo [ip_address]:[port]

例如 : mongo localhost:4000

4. 創建數據庫

接下來在交互環境中執行下面命令來創建數據庫:

use library

上述命令創建了一個名為 library 的數據庫。

然后我們可以通過下面的命令來查看剛創建的數據庫,下面命令列出系統中所有的數據庫:

show dbs;

你會注意到,你剛創建的數據庫并沒有列出來,這是因為 MongoDB 只有在需要的時候才會創建數據庫,因此你需要往數據庫里添加點數據。

5. 往數據庫中插入數據

首先我們通過以下命令創建兩本書:

> book1 = {name : "Understanding JAVA", pages : 100}
> book2 = {name : "Understanding JSON", pages : 200}

然后將這兩本書保持到名為 books 的集合中:

> db.books.save(book1)
> db.books.save(book2)

上述命令將在 library 數據庫中創建一個名為 books 的集合(也就是SQL數據庫中的表),下面命令將列出我們剛添加的兩本書:

> db.books.find();

{ "_id" : ObjectId("4f365b1ed6d9d6de7c7ae4b1"), "name" : "Understanding JAVA", "pages" : 100 }
{ "_id" : ObjectId("4f365b28d6d9d6de7c7ae4b2"), "name" : "Understanding JSON", "pages" : 200 }

添加更多的記錄:

> book = {name : "Understanding XML", pages : 300}
> db.books.save(book)
> book = {name : "Understanding Web Services", pages : 400}
> db.books.save(book)
> book = {name : "Understanding Axis2", pages : 150}
> db.books.save(book)

6. 編寫 Map 函數

接下來我們編寫一個搜索功能,用來查找超過250頁的圖書:

> var map = function() {
var category;
if ( this.pages >= 250 ) 
category = 'Big Books';
else 
category = "Small Books";
emit(category, {name: this.name});
};

所返回的結果:

{"Big Books",[{name: "Understanding XML"}, {name : "Understanding Web Services"}]);
{"Small Books",[{name: "Understanding JAVA"}, {name : "Understanding JSON"},{name: "Understanding Axis2"}]);

7. 編寫 Reduce 函數

> var reduce = function(key, values) {
var sum = 0;
values.forEach(function(doc) {
sum += 1;
});
return {books: sum};
};

8. 在 books 集合中運行 MapReduce

> var count  = db.books.mapReduce(map, reduce, {out: "book_results"});
> db[count.result].find()

{ "_id" : "Big Books", "value" : { "books" : 2 } }
{ "_id" : "Small Books", "value" : { "books" : 3 } } 

上述結果表明我們有兩本大書和三本小書。

利用 MongoDB 交互環境可以做任何事情,用 Java 也一樣,但是你需要下載一些必須的jar包

下面是 Java 的源碼:

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceOutput;
import com.mongodb.Mongo;

public class MongoClient {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Mongo mongo;

  try {
   mongo = new Mongo("localhost", 27017);
   DB db = mongo.getDB("library");

   DBCollection books = db.getCollection("books");

   BasicDBObject book = new BasicDBObject();
   book.put("name", "Understanding JAVA");
   book.put("pages", 100);
   books.insert(book);

   book = new BasicDBObject();  
   book.put("name", "Understanding JSON");
   book.put("pages", 200);
   books.insert(book);

   book = new BasicDBObject();
   book.put("name", "Understanding XML");
   book.put("pages", 300);
   books.insert(book);

   book = new BasicDBObject();
   book.put("name", "Understanding Web Services");
   book.put("pages", 400);
   books.insert(book);

   book = new BasicDBObject();
   book.put("name", "Understanding Axis2");
   book.put("pages", 150);
   books.insert(book);

   String map = "function() { "+ 
             "var category; " +  
             "if ( this.pages >= 250 ) "+  
             "category = 'Big Books'; " +
             "else " +
             "category = 'Small Books'; "+  
             "emit(category, {name: this.name});}";

   String reduce = "function(key, values) { " +
                            "var sum = 0; " +
                            "values.forEach(function(doc) { " +
                            "sum += 1; "+
                            "}); " +
                            "return {books: sum};} ";

   MapReduceCommand cmd = new MapReduceCommand(books, map, reduce,
     null, MapReduceCommand.OutputType.INLINE, null);

   MapReduceOutput out = books.mapReduce(cmd);

   for (DBObject o : out.results()) {
    System.out.println(o.toString());
   }
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

OSCHINA 原創翻譯自:facilelogin

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!