这是我遇到问题的具体查询。我正在使用Lift-mongo- 记录,以便我可以使用Rogue。我很高兴使用Rogue特有的 语法,或其他任何工作。
虽然通过下面提到的java使用javascript字符串有很好的例子,但我想知道最佳实践可能是什么。
想象一下,有一个像
这样的表格comments {
_id
topic
title
text
created
}
所需的输出是主题列表及其计数,例如
因此,用户可以通过
查看按计数排序的列表这是一些伪造的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 );
上述变化无法编译。
我可以问“我做错了什么”,但我想我可以做到 混乱更加尖锐:
我发现的最近一篇文章涵盖了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
猜测:
这可以从命令行开始工作:
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
答案 0 :(得分:2)
以下对我有用:
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
是ArrayBuffer
满coll.T
,可以通常的方式处理。
答案 1 :(得分:1)
似乎是一个错误 - 某处。
目前,我现在使用eval()(更慢,更不安全)的工作方式不太理想......
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查询输出表。