Эффективный способ отображения вложенного дерева с монгоидом и рельсами - PullRequest
3 голосов
/ 09 мая 2011

У меня есть дерево комментариев, вложенное в документ, используя mongoid embeds_many_recursively вот так:

   Document: {
    ...
    comments: [{
      ...
      updated_at,
      child_comments: [{
        ...
        updated_at
        child_comments: [{...},{...}],
        ...},{...}]
      ...}]
    ...}]
   ...}

Каков наиболее эффективный способ передачи его представлению способом, упорядоченным по атрибуту 'comment updated_at' первого уровня?

На данный момент я придумал это внутри основной модели документа:

  def flatten_comments
    @flat_comments = []
    self.comments.order_by([[:updated_at, :desc]]).each do |comment|
      flatten_comments_iterator(comment)
    end
    return @flat_comments
  end

  def flatten_comments_iterator(comment)
    @flat_comments << comment
    comment.child_comments.each {|reply| flatten_comments_iterator(reply)}
  end

, а затем просто итерация в представлении массива.

Проблемы: 1) при рекурсивном выравнивании порядок где-то теряется, и я не могу понять, где, шаг за шагом на бумаге, кажется, добавляются элементы в нужном порядке, возможно, что-то связанное с областью видимости и доступом к переменной класса.

2) Я не уверен, что это самый эффективный способ простого поиска.

Был бы благодарен за совет и за опыт в том, как эффективно решать такие задачи.

1 Ответ

2 голосов
/ 19 мая 2011

Существует в основном 2 подхода к проектированию (один из них такой же, как у вас), которые документированы на примерах моделирования драйвера ruby ​​.Существует также похожий вопрос по SO .

По поводу другой проблемы: в рекурсивности нет ничего плохого, в общем, если комментарии не имеют большой глубины вложенности.Однако ваша реализация не является поточно-ориентированной, поскольку использует переменные экземпляра, а не локальные переменные.Чтобы справиться с этим, вы должны преобразовать @flat_comments в локальную переменную и передать его в качестве параметра методу flatten_comments_iterator.

Совет: поскольку любая рекурсия метода может быть преобразована в итерацию то, что вы можете реализовать, - это итеративный обход предзаказа графа.

...