其实说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。土死了……