使用has_one进行Mongoid Map Reduce

时间:2013-02-13 13:24:37

标签: ruby ruby-on-rails-3 mongodb mapreduce mongoid

我在我正在制作的应用程序中使用Mongoid和MongoDB。我有一个用户有一个这样的配置文件:

class User

 field :email, :type => String
 field :name, :type => String
 field :date_of_birth, :type => DateTime
 has_one :profile

end

class Profile

 field :votes, :type => Hash
 field :biography, :type => String
 belongs_to :profile

end

投票哈希的结构如下:

profile : {
  "user_id" : ObjectId("511b76b0e80c505750000031"),
  "votes": {
    "vote_count": 3,
    "up_votes": 3,
    "down_votes": 0
  }
}

我正在运行map reduce,如下所示:

map = "
  function () {
    values = {
      name: this.name
    }
    emit(this._id, values);
  }
"

reduce = "
  function (key, emits) {
    return emits;
  }
"

User.map_reduce(map, reduce).out(replace: "leaderboards").each do |document|
  ap document
end

这很好用,并在Mongo中创建一个名为排行榜的新集合。但是,我试图从配置文件中映射一些数据,因此它包含配置文件中的vote_count字段。

基本上使我的地图功能看起来像这样:

map = "
  function () {
    values = {
      name: this.name,
      votes: this.profile.votes.vote_count
    }
    emit(this._id, values);
  }
"

但是我很难抓住与用户关联的个人资料。有谁知道如何从用户档案中提取数据?

如果有什么不清楚,请告诉我。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

MongoDB无法在服务器端对来自不同集合的数据进行“连接” - 您必须在客户端应用程序中执行这些操作,或者更好地考虑document embedding,尤其是当有您的用户和个人资料集合之间的1:1关系。

现在,如果设计更改不是一个选项,您可以按顺序执行两个mapReduce():

  1. 您在User上使用的那个,但使用user_id作为键,并添加名称 作为一个领域
  2. 使用相同的user_id键和一个map上的mapReduce vote_count,在排行榜中指定merge output 集合
  3. 这有帮助吗?

    问候

    罗纳德