用MongoDB实现MapReduce

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页的图书:

1 var map = function() {
2 var category;
3 if this.pages >= 250 )
4 category = 'Big Books';
5 else
6 category = "Small Books";
7 emit(category, {name: this.name});
8 };

所返回的结果:

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

7. 编写 Reduce 函数

1 var reduce = function(key, values) {
2 var sum = 0;
3 values.forEach(function(doc) {
4 sum += 1;
5 });
6 return {books: sum};
7 };

8. 在 books 集合中运行 MapReduce

1 var count  = db.books.mapReduce(map, reduce, {out: "book_results"});
2 > db[count.result].find()
3  
4 "_id" "Big Books""value" : { "books" : 2 } }
5 "_id" "Small Books""value" : { "books" : 3 } }

上述结果表明我们有两本大书和三本小书。

利用 MongoDB 交互环境可以做任何事情,用 Java 也一样,但是你需要下载一些必须的jar包

下面是 Java 的源码:

01 import com.mongodb.BasicDBObject;
02 import com.mongodb.DB;
03 import com.mongodb.DBCollection;
04 import com.mongodb.DBObject;
05 import com.mongodb.MapReduceCommand;
06 import com.mongodb.MapReduceOutput;
07 import com.mongodb.Mongo;
08  
09 public class MongoClient {
10  
11  /**
12   * @param args
13   */
14  public static void main(String[] args) {
15  
16   Mongo mongo;
17    
18   try {
19    mongo = new Mongo("localhost"27017);
20    DB db = mongo.getDB("library");
21  
22    DBCollection books = db.getCollection("books");
23  
24    BasicDBObject book = new BasicDBObject();
25    book.put("name""Understanding JAVA");
26    book.put("pages"100);
27    books.insert(book);
28     
29    book = new BasicDBObject(); 
30    book.put("name""Understanding JSON");
31    book.put("pages"200);
32    books.insert(book);
33     
34    book = new BasicDBObject();
35    book.put("name""Understanding XML");
36    book.put("pages"300);
37    books.insert(book);
38     
39    book = new BasicDBObject();
40    book.put("name""Understanding Web Services");
41    book.put("pages"400);
42    books.insert(book);
43   
44    book = new BasicDBObject();
45    book.put("name""Understanding Axis2");
46    book.put("pages"150);
47    books.insert(book);
48     
49    String map = "function() { "+
50              "var category; " 
51              "if ( this.pages >= 250 ) "
52              "category = 'Big Books'; " +
53              "else " +
54              "category = 'Small Books'; "
55              "emit(category, {name: this.name});}";
56     
57    String reduce = "function(key, values) { " +
58                             "var sum = 0; " +
59                             "values.forEach(function(doc) { " +
60                             "sum += 1; "+
61                             "}); " +
62                             "return {books: sum};} ";
63     
64    MapReduceCommand cmd = new MapReduceCommand(books, map, reduce,
65      null, MapReduceCommand.OutputType.INLINE, null);
66  
67    MapReduceOutput out = books.mapReduce(cmd);
68  
69    for (DBObject o : out.results()) {
70     System.out.println(o.toString());
71    }
72   catch (Exception e) {
73    // TODO Auto-generated catch block
74    e.printStackTrace();
75   }
76  }
77 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值