Although you can "include" properties from other documents in the index (using LoadDocument), it is not recommended that you use it extensively because you need to rebuild the index more often.
In your case, you can simulate your song document to include links to Artist, Genre, etc. by id and request on this subject, and then use Transformer to convert the result to the desired “view model”. Use LoadDocument in the transformer to select artist name, genre name, etc. And return the converted result. Conversion is performed on the server side upon request.
Your song essence (simplified) might look like this:
public class Song { public string Id { get; set; } public string Name { get; set; } public string ArtistId { get; set; } }
And an index like this:
public class Song_ByArtist : AbstractIndexCreationTask<Song> { public Song_ByArtist() { Map = songs => from song in songs select new { song.Name, song.ArtistId }; } }
In combination with a transformer:
public class Song_Artist_Transformer : AbstractTransformerCreationTask<Song> { public Song_Artist_Transformer() { TransformResults = results => from song in results let artist = LoadDocument<Artist>(song.ArtistId) select new SongArtistViewModel { SongName = song.Name, ArtistName = artist.Name }; } }
You can request artists songs and return a performance model, including artist name, with:
using (var session = _documentStore.OpenSession()) { var results = session.Query<Song, Song_ByArtist>() .Where(x => x.ArtistId == "artists/1") .TransformWith<Song_Artist_Transformer, SongArtistViewModel>(); }
This will return all the songs for the artist / 1 artist, transformed as a presentation model with the song name and artist name.
So, on the bottom line: model your song document to include links to other documents (aggregates, if after DDD), where necessary, and then include the information you need using transformers. Transformers can be thought of as something like “View” in relational db.
Note. Make one combined index for your song’s document, where you index all the properties (both song properties and links), and then use several transformers to represent the data as needed. It is often better to use one large index for one document instead of several small ones for the same type of document. In this example, I just matched the name and identifier of the artist so that it is simple.
Hope this helps!