Я работаю над побочным проектом по созданию форума, построенного поверх RavenDB. В настоящее время я пытаюсь выяснить отношения между авторами тем и пользователем «Последний ответ» в теме. В типичной реляционной модели я бы просто сохранил FK для пользователя, опубликовавшего тему, и присоединился к таблице ответов, чтобы получить автора самых последних ответов. Очевидно, что это не вариант использования Raven или любого другого хранилища документов.
Что было бы наиболее «оптимальным» способом осуществить это? В настоящее время я подбрасываю пару идей.
Идея 1: Сохраните FK автора в модели темы, добавьте объект JsonIgnored User, который я буду заполнять при загрузке темы, используя Include в моей загрузке сеанса (поэтому один запрос со стороны клиента просто делает загрузку сама и модель немного сложная). Затем, возможно, используйте индекс уменьшения карты, чтобы получить автора самых последних ответов (или даже тот же метод, что и получение автора темы, поэтому в зависимости от 1 или 2 запросов).
Идея 2: Сохранение в модели как автора, так и последнего ответившего пользователя. Основная «проблема» здесь — возможность устаревших данных (скажем, при изменении имени пользователя). Однако потенциально это можно облегчить с помощью фоновой задачи (или просто помнить об этом при обновлении пользовательского документа и возврате ко всем сообщениям от пользователя).
Пример рассматриваемых моделей.
public class User
{
public string Id { get; set; }
public string UserName { get; set; }
public string PasswordHash { get; set; }
}
public class Topic
{
public string Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
// Idea 1 Relationships
public string AuthorId { get; set; }
[JsonIgnore]
public User Author { get; set; } // Would need to be populated on loads from an Include on AuthorId
public string MostRecentReplyUserId { get; set; }
[JsonIgnore]
public User MostRecentReplyUser { get; set; } // Same as Author
// Idea 2 Relationships
public User Author { get; set; }
public User MostRecentReplyUser { get; set; }
}
Примечание. Я бы, скорее всего, добавил в модель User метод, возвращающий «чистую» версию, в которой я удалял бы такие вещи, как PasswordHash, и использовал бы их в Save for Idea 2.