08 March 2011

其实说Lift里不够准确,Lift对MapReduce没做什么封装,基本上就是直接调用mongo-java-driver的API。

举例说明,计算所有URL的点击次数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    def countClicks = {
      MongoDB.useCollection(shortenedUrl.collectionName) {
        x => {
          val map = """function() { emit("totalClickCount", this.%s); }""" format ShortenedUrl.clickCount.name
          val reduce = """function(key, values) { return Array.sum(values); }"""
          val results = x.mapReduce(map, reduce, null, null).results
 
          /**
           * all numbers returned by mongodb is Double since this is how number defined by javascript
           */
          if (results.hasNext) results.next.get("value").asInstanceOf[Number].intValue.toString else "0"
        }
      }
    }

map的时候把this.clickCount的值塞给”totalClickCount”这个key,reduce把所有这些值加起来,MongoDB会生成一个临时的collection,从里面选择“value”这个字段就可以了。

需要注意的是所有返回的数值类型都是Double,虽然BSON里对各种类型都有定义,但是目前为止MongoDB只支持返回Double。对js了解的人可能会比较清楚,但我就惨了。调了很长时间,一个bit一个bit的看,甚至还去MongoDB的JIRA上问:http://jira.mongodb.org/browse/SERVER-2688。土死了……



blog comments powered by Disqus