I'm working on a side project to create a Forum built on top of RavenDB. I am currently trying to work out the relationship between Authors of Topics, and the "Last Reply" user on a topic. In a typical relational model I would simply store the FK to the User who posted the topic, and have a join off to the replies table to get the most recent replies author. This is obviously not the use case for Raven or any Document store for that matter.
What would be the most "optimal" way of pulling this off? Currently I'm tossing around a couple ideas.
Idea 1: Save the FK of the Author on the Topic model, add a JsonIgnored User object that I will populate on the Topic load by using an Include in my session load (so one request so far from the client side, just makes the Load itself and model a bit complicated). Then possibly using a map-reduce index to get the most recent replies author (or even the same method as getting the Topic Author, so 1 or 2 queries depending).
Idea 2: Saving both the Author and the most recent reply User on the model. Main "problem" here is the potential for stale data (say if a username changes). However that could potentially be alleviated with a background task (or simply keeping that in mind when updating a user document and going back over all posts from a user).
Example of the models in question.
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; }
}
Note: I would likely add a method to the User model to return a "clean" version where I scrub out things like the PasswordHash and use that on the Save for Idea 2.