首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Scala (Casbah/Rogue)在MongoDB中按(聚合地图约简函数)分组

使用Scala (Casbah/Rogue)在MongoDB中按(聚合地图约简函数)分组
EN

Stack Overflow用户
提问于 2011-09-04 21:42:40
回答 2查看 3.6K关注 0票数 2

下面是我遇到麻烦的一个特定查询。我用的是升降机-芒果唱片,这样我就可以用盗贼了。我很乐意使用Rogue特定的语法,或者任何有用的方法。

虽然下面提到了通过java使用javascript字符串的好例子,但我想知道最佳实践可能是什么。

想象一下这里有一张桌子

代码语言:javascript
复制
comments {
 _id
 topic
 title
 text
 created
}

所需的输出是主题及其计数的列表,例如

  • 猫(24)
  • 狗(12)
  • 小鼠(5)

这样,用户就可以看到一个列表,它是按计数顺序排列的,一个独立的/组的列表是

下面是一些psuedo SQL:

代码语言:javascript
复制
SELECT [DISTINCT] topic, count(topic) as topic_count
FROM comments
GROUP BY topic
ORDER BY topic_count DESC
LIMIT 10
OFFSET 10

一种方法是使用一些DBObject DSL,如

代码语言:javascript
复制
val cursor  = coll.group( MongoDBObject(
"key" -> MongoDBObject( "topic" -> true ) ,
//
"initial" -> MongoDBObject( "count" ->  0 ) ,
"reduce" -> "function( obj , prev) { prev.count += obj.c; }"
 "out" -> "topic_list_result"
))

 [...].sort( MongoDBObject( "created" ->
-1 )).skip( offset ).limit( limit );

以上的变体不编译。

我可以问“我做错了什么”,但我想我可以让我的困惑更加尖锐:

required?

  • should

  • 可以直接链接结果还是需要"out“?

  • 可以期望什么样的输出?我的意思是,我是在游标上迭代,还是”out“param

  • 是"cond”,我正在使用count(),或者distinct()

  • some示例包含"map“param.

我最近发现的一篇关于java驱动程序的文章暗示我应该使用字符串而不是DSL:http://blog.evilmonkeylabs.com/2011/02/28/MongoDB-1_8-MR-Java/

无论是在客栈还是在盗贼,这是首选的方法吗?

更新: 9/23

这在Scala/Casbah中失败(编译但产生错误{MapReduceError 'None'} )

代码语言:javascript
复制
val map = "function (){ emit({ this.topic }, { count: 1 }); }"
val reduce = "function(key, values) {  var count = 0; values.forEach(function(v) { count += v['count']; }); return {count: count}; }"
val out  = coll.mapReduce(  map ,  reduce  , MapReduceInlineOutput  )
ConfiggyObject.log.debug( out.toString() )

我在看了https://github.com/mongodb/casbah/blob/master/casbah-core/src/test/scala/MapReduceSpec.scala之后就决定了上面的内容。

猜测:

  • 我误解了toString方法和out.object是什么?
  • 缺失终结?
  • 缺失输出规范?
  • ?

这按照命令行的要求工作:

代码语言:javascript
复制
   map = function (){
        emit({ this.topic }, { count: 1 });
    }

    reduce = function(key, values) {  var count = 0; values.forEach(function(v) { count += v['count']; }); return {count: count}; };

    db.tweets.mapReduce( map, reduce,  { out: "results" } ); //
    db.results.ensureIndex( {count : 1});
    db.results.find().sort( {count : 1});

更新这个问题还没有作为一个错误提交到Mongo上。https://jira.mongodb.org/browse/SCALA-55

EN

回答 2

Stack Overflow用户

发布于 2012-03-24 05:33:12

以下几点对我有用:

代码语言:javascript
复制
val coll = MongoConnection()("comments")
val reduce = """function(obj,prev) { prev.csum += 1; }"""
val res = coll.group( MongoDBObject("topic"->true),
                       MongoDBObject(), MongoDBObject( "csum" -> 0 ), reduce)

res是一个充满coll.TArrayBuffer,它可以按照通常的方式处理。

票数 2
EN

Stack Overflow用户

发布于 2011-09-27 16:37:29

好像是个窃听器-在某个地方。

目前,我有一个不太理想的解决办法,现在使用eval() (较慢,不太安全).

代码语言:javascript
复制
db.eval( "map = function (){ emit( { topic: this.topic } , { count: 1 }); } ; ");
db.eval( "reduce = function(key, values) { var count = 0; values.forEach(function(v) { count += v['count']; }); return {count: count}; }; ");
db.eval( " db.tweets.mapReduce( map, reduce, { out: \"tweetresults\" } ); ");
db.eval( " db.tweetresults.ensureIndex( {count : 1}); ");

然后,我通常通过casbah查询输出表。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7302300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档