【问题标题】:ruby Parent-Child recursion optimisationruby 父子递归优化
【发布时间】:2013-06-28 18:10:31
【问题描述】:

我目前有一个 Rails 应用程序,其中包含以父子关系链接的数千条记录。

我想要以有效方式返回每条记录的所有后代或祖先的方法。我有一个递归执行此操作的工作方法,但它当前填充大量数组(最多 100k 条记录),然后将它们展平并删除重复项。有没有比我当前需要数小时才能运行所有记录的代码更有效的方法来实现这一点?我不认为 Ancestry 之类的 gem 适合,因为我没有严格的树形结构。

提前非常感谢。

class Record < ActiveRecord::Base

  has_many :children, through: :reverse_relationships, source: :child
  has_many :parents, through: :relationships, source: :parent


  def all_children
    children.map do |child|
      [child] + child.all_children
    end.flatten.uniq
  end

  def all_parents
    parents.map do |parent|
      [parent] + parent.all_parents
    end.flatten.uniq
  end
end

【问题讨论】:

  • through: 在我看来不像经典的父子层次结构,这是有原因的(使递归变慢)吗?
  • 我认为这是建立自我参照关系的合适方式。我的记录是计划中的活动,每个活动都链接到其他活动。如果有更好的方法,请告诉我?
  • 伙计们,看起来嵌套集合不是我所追求的,因为我的对象可以有多个父对象。因此,如果有人可以提供一种简单的方法来提高我所拥有的代码的性能,将不胜感激。
  • 如果你可以有多个父母和多个孩子,那么就有可能出现循环循环,你的递归代码就会中断。这描述了一个图结构。

标签: ruby-on-rails ruby activerecord recursion parent-child


【解决方案1】:

查看一种稍微不同的方式来表示嵌套集中的层次结构。 https://github.com/collectiveidea/awesome_nested_set

这消除了递归查询。

【讨论】:

  • DGM 你能告诉我当一个项目有多个父项时嵌套集是否有效?在我的应用程序中就是这种情况,这与我看到的所有示例形成鲜明对比。
  • 哦,不,我错过了。嵌套集纯粹是分层的。
  • 如果您的查询总是按照仅遵循父关系或仅遵循子关系的方式排列自己,我可以设想使用具有两组不同指针的嵌套集的可能性。称它为 A 和 B,因此您将拥有以下字段:a_rgt、a_lft、a_parent_id、b_rgt、b_lft、b_parent_id ...我不确定是否有任何现有的 gem 支持属于两个不同的嵌套集,因此您可能必须滚动您的拥有。
【解决方案2】:

就其本质而言,使用最直接的模式是非常低效的。您可能需要考虑实施Nested Set Model。快速搜索显示 Rails 有很多宝石。

【讨论】:

    猜你喜欢
    • 2021-03-28
    • 1970-01-01
    • 2019-01-27
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 2019-12-21
    相关资源
    最近更新 更多