【问题标题】:Rails/Mongoid best way to save sortable ordered listRails/Mongoid 保存可排序列表的最佳方式
【发布时间】:2014-03-08 16:08:49
【问题描述】:

我从我的数据库中提取了一个可排序的玩家列表。用户可以按照自己的喜好对它们进行排名。

在与每个玩家的偏好相关联的数据库中存储该顺序并以相同顺序检索玩家统计数据的最佳方式是什么?

现在我正在通过@playersdraftlist = @draftlist.map { |id| Player.find(id) } 检索,但这会多次访问数据库。

所以,目前,我有一个用户模型和一个草稿模型。草稿只有一个关联的user_id

1) 将被征召者存储为用户字段而不是单独的模型会更好吗?

2) 当我需要保留欺骗和订单时,有没有更好的方法来存储这样的列表?

结构:

PlayerDraft 模型有一个关联的user_id

  draftees: [
    "52f4fd9f52e39bc0c15674ea", #Peyton
    "52f4fd9f52e39bc0c15674eb", #Tom
    "52f4fd9f52e39bc0c15674ea"  #Peyton
  ],
  user_id: "52f581096b657612fe020000"

@draftees = Draft.find(user_id = current_user._id).first.draftees 将返回 Draftees 数组。

调用Player.find(@draftees) 将删除重复项并按_id 排序。

编辑

这是我的糟糕解决方案:

  def index
    @players = Player.all

    if current_user.draft_list.draftees == [""]
      @playersdraftlist = ""

    else
      # Get all picks for current user
      @picks = current_user.draft_list.draftees
      @draft = Player.find(@picks)
      @playersdraftlist = @picks.map { |id| Player.find(id) }

    end
  end

【问题讨论】:

  • 查看我的更新。这能解释清楚吗?

标签: ruby-on-rails gem mongoid jquery-ui-sortable


【解决方案1】:

做到这一点的方法是使用mongoid中的identity map。 这里有更多细节:http://mongoid.org/en/mongoid/docs/identity_map.html

但执行此操作的简短方法是在您的 mongoid.yml 中设置以下属性: identity_map_enabled: true

然后搜索以下内容:Player.find(@draftees) 这将按照您传入的数组的顺序返回您的被选中者。需要注意的是,它不会返回重复项,因此如果使用上面的 @draftees 数组,则只会返回两个值(顺序基于第一次出现id,所以它会首先返回 id 为“52f4fd9f52e39bc0c15674ea”的玩家,然后是 id 为“52f4fd9f52e39bc0c15674eb”的玩家)。因此,您将不得不通过某种抽象重新创建重复项。

这是一种可能的方法,它的灵感来自下面@muistooshort 发表的评论:

在您的User 类中添加以下函数

def get_draftee_list
  players = Player.find(self.draftees).each_with_object({}) { |p, h| h[p.id] = p } 
  return self.draftees.map { |id| players[Moped::BSON::ObjectId.from_string(id)] }
end

注意:这是在 Mongoid 3 上测试的

这应该可以解决您的问题,因为对 raw_data.find(id) 的每次调用都是从存储在内存中的初始查询中搜索结果集,而不是对数据库进行另一个查询

【讨论】:

  • 好消息。您的答案是正确的,但要完全计算,我需要知道如何包含重复项。到目前为止,我最好还是继续使用哈希映射。
  • 好的,我已经更新了我将如何做的答案,这样您就不会连续进行数据库调用。我现在期待一个赞成票:P
  • 听起来不错。我会更新我的项目并澄清是否需要。谢谢你。这应该比我目前的方法便宜,对吗?
  • 我认为会的,但是您应该检查您的日志以查看您之前的方法花费了多长时间与此方法花费了多长时间来确认。我建议您将新的 relic gem 添加到您的应用程序中,并查看每种方式进行了多少数据库查询以及返回每个查询需要多长时间
  • @alalani,我越来越近了……得摆弄一下。注意:对于 mongoid-4,Moped::BSON 只是 BSON。 :)
猜你喜欢
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
相关资源
最近更新 更多