使用Ruby驱动程序的MongoDB组

使用Ruby驱动程序的MongoDB组,ruby,mongodb,Ruby,Mongodb,我试图带回来一份年/月组合列表,其中包含描述博客帖子的计数。其想法是,它们将以如下方式显示: 2010年1月(1个员额) 2009年12月(2个员额) 我使用MongoDB JS shell成功地实现了这一点,它以有用的格式返回结果: db.posts.group({ keyf: function(x){ return { month: x.datetime.getMont

我试图带回来一份年/月组合列表,其中包含描述博客帖子的计数。其想法是,它们将以如下方式显示:

  • 2010年1月(1个员额)
  • 2009年12月(2个员额)
我使用MongoDB JS shell成功地实现了这一点,它以有用的格式返回结果:

db.posts.group({ 
    keyf: function(x){ 
                      return { 
                              month: x.datetime.getMonth(), 
                              year:x.datetime.getFullYear() 
                      }; 
    }, 
    reduce: function(x,y){ y.count++ }, 
    initial:{count:0} 
})
结果:

[ { "month" : 0, "year" : 2010, "count" : 3 },
  { "month" : 0, "year" : 1970, "count" : 1 } ]
这很好,正是我想要的。然而,试图将其转换为适合ruby驱动程序的代码,我无法让它工作。我查看了文档,根据我的理解,以下内容应该会产生相同的结果(我使用的是MongoMapper,因此是
Post.collection
):

我没有返回有用的数据数组,而是得到了这样的混乱:

{
  "function(x) { return { month: x.datetime.getMonth(), year:x.datetime.getFullYear() }; }" => nil, 
  "count" => 4.0
}

看起来要么它完全无视自己的文档(以及我对源代码的理解!),要么我在这里遗漏了一些基本的东西。我几乎要发疯了,感激地接受了任何帮助。

这是非常奇怪的行为。我只是在本地运行了你的代码,一切正常。您能否验证您正在使用的驱动程序版本为0.18.2?如果是这样的话,请确保这是唯一安装的版本(作为一个健全性检查)

我不认为这会有什么不同,但我不是在运行MongoMapper的#group——我只是在单独使用gem。你也可以试试。以下是我运行的代码:

require 'rubygems'
require 'mongo'

d = Mongo::Connection.new.db('blog')
c = d['post']

p c.group("function(x) { return { month: x.date.getMonth(), year:x.date.getFullYear() }; }", 
  nil, 
  { :count => 0 }, 
  "function(x,y){y.count++}", 
  true)

我已经检查了版本,安装了0.18和0.18.2。我已经删除了旧版本并更新了MongoMapper(我依赖的版本是0.18)。这个问题仍然存在。我也试着像你一样使用驱动程序,但在我的情况下,它仍然失败。我不明白为什么你和我的行为会不同?编辑:在自己的脚本中尝试此操作会产生正确的结果。它似乎只是在我的rails应用程序中失败了。不确定Rails对此可能有什么影响。我认为最好的办法是你为我和约翰(来自MongoMapper)创建一个完全失败的测试用例。原来是版本差异0.18到0.18.2。在我删除了旧的gem并更新了所有内容之后,我忘记了重新启动dev服务器。回过头来看github上的0.18源代码,我发现在0.18.2和0.18.2之间,添加了对keyf代码的支持,这确实修复了它。我觉得自己有点傻:)
require 'rubygems'
require 'mongo'

d = Mongo::Connection.new.db('blog')
c = d['post']

p c.group("function(x) { return { month: x.date.getMonth(), year:x.date.getFullYear() }; }", 
  nil, 
  { :count => 0 }, 
  "function(x,y){y.count++}", 
  true)