这是我遇到问题的具体查询。我正在使用 Lift-mongo- 记录以便我可以使用 Rogue。我很高兴使用 Rogue 专用 syntax ,或任何有效的方法。
虽然有下面提到的通过 java 使用 javascript 字符串的很好示例,但我想知道最佳实践可能是什么。
假设这里有一张 table
comments {
_id
topic
title
text
created
}
例如,所需的输出是主题及其计数的列表
- 猫 (24)
- 狗 (12)
- 老鼠 (5)
因此用户可以看到一个列表,按计数排序,不同/分组依据
这是一些伪 SQL:
SELECT [DISTINCT] topic, count(topic) as topic_count
FROM comments
GROUP BY topic
ORDER BY topic_count DESC
LIMIT 10
OFFSET 10
一种方法是使用一些 DBObject DSL,例如
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 );
上面的变体不编译。
我可以问“我做错了什么”,但我想我可以 困惑更严重:
- 我可以直接链接结果还是需要“输出”?
- 我可以期待什么样的输出——我的意思是,我是否迭代了一个 光标,或“out”参数
- 是否需要“cond”?
- 我应该使用 count() 还是 distinct()
- 一些示例包含“ map ”参数...
我最近发现一篇关于 java 驱动程序的帖子暗示我应该 使用字符串而不是 DSL: http://blog.evilmonkeylabs.com/2011/02/28/MongoDB-1_8-MR-Java/
这会是 casbah 或 Rogue 中的首选方法吗?
更新:9/23
这在 Scala/Casbah 中失败(编译但产生错误 {MapReduceError 'None'})
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 是什么?
- 缺少定稿?
- 缺少输出规范?
- https://jira.mongodb.org/browse/SCALA-43 ?
这在命令行中按需工作:
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
最佳答案
以下对我有用:
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.T
的 ArrayBuffer
,可以用通常的方式处理。
关于scala - 使用 Scala (Casbah/Rogue) 在 MongoDB 中分组(聚合 Map Reduce 函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7302300/