Рекурсивная выборка в самоотношениях Grails

У меня есть следующий класс домена Grails, содержащий отношение к себе.

class Message {
    static hasMany = [replies: Message]

    Message isReplyTo
    User author
    String title
    String text
    Date createdAt
    Date lastUpdated
}

Я хочу написать запрос, который может делать две вещи

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

    Message 1
    ---- Reply 1
    ---- Reply 2
    -------- SubReply 1
    
  2. Учитывая сообщение, которое является ответом на другое сообщение, также создайте список, как указано выше, включая того родителя, к которому относится данное сообщение (ответ).

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


person Pila    schedule 28.11.2018    source источник


Ответы (1)


Есть несколько способов обработки этого типа структуры, и в Интернете нет недостатка в примерах этого типа древовидных отношений.

В простейшем подходе; у вас может быть структура Parent Child, где родитель null будет сигнализировать о вершине дерева, а «нулевой» дочерний элемент будет сигнализировать о конце этой ветви. Это простая и эффективная структура, но сбор метрик может быть затруднен, поскольку вам всегда придется рекурсивно выполнять поиск по всему потоку.

  Message{
    ...
    Message parent
    Message child
  }

В этом сообщении показана хорошая рекурсия в примере GSP:

Другой шаблон для этого — материализованный путь. Это немного сложно реализовать, но с ним легко работать, когда он на месте. Материализованные пути также намного проще собирать метрики, такие как количество ответов, и делать хлебные крошки тоже намного проще.

  Message{
    ...
    Message parent
    String path //would like something like this: 1/2/3/4
  }

Пример поиска материализованного пути можно найти в Google или этот пост.

person Michael J. Lee    schedule 28.11.2018