You are currently browsing legacy 3.0 version of documentation. Click here to switch to the newest 4.2 version.

We can help you with migration to the latest RavenDB

Contact Us Now
see on GitHub

Indexing Related Documents

To extend indexing capabilities and simplify many scenarios, we have introduced the possibility for indexing related documents.

Example I

Firstly, let's consider a simple Product - Category scenario where you want to look for a Product by Category Name.

Without this feature, the index that had to be created would be a fairly complex multiple map-reduce index. This is why the LoadDocument function was introduced.

public class Products_ByCategoryName : AbstractIndexCreationTask<Product>
{
	public class Result
	{
		public string CategoryName { get; set; }
	}

	public Products_ByCategoryName()
	{
		Map = products => from product in products
					select new
					{
						CategoryName = LoadDocument<Category>(product.Category).Name
					};
	}
}
store.DatabaseCommands.PutIndex("Products/ByCategoryName", new IndexDefinition
{
	Map = @"from product in products
		select new
		{
			CategoryName = LoadDocument(product.Category).Name
		}"
});

Now we will be able to search for products using the Category Name as a parameter:

IList<Product> results = session
	.Query<Products_ByCategoryName.Result, Products_ByCategoryName>()
	.Where(x => x.CategoryName == "Beverages")
	.OfType<Product>()
	.ToList();

Example II

Our next scenario will show us that indexing of more complex relationships is also trivial. Let's consider the following case:

public class Book
{
	public string Id { get; set; }

	public string Name { get; set; }
}

public class Author
{
	public string Id { get; set; }

	public string Name { get; set; }

	public IList<string> BookIds { get; set; }
}

Now, to create an index with Author Name and list of Book Names, we need do the following:

public class Authors_ByNameAndBooks : AbstractIndexCreationTask<Author>
{
	public class Result
	{
		public string Name { get; set; }

		public IList<string> Books { get; set; }
	}

	public Authors_ByNameAndBooks()
	{
		Map = authors => from author in authors
					select new
					{
						Name = author.Name,
						Books = author.BookIds.Select(x => LoadDocument<Book>(x).Name)
					};
	}
}
store.DatabaseCommands.PutIndex("Authors/ByNameAndBooks", new IndexDefinition
{
	Map = @"from author in docs.Authors
		select new
		{
			Name = author.Name,
			Books = author.BookIds.Select(x => LoadDocument(x).Id)
		}"
});

IList<Author> results = session
	.Query<Authors_ByNameAndBooks.Result, Authors_ByNameAndBooks>()
	.Where(x => x.Name == "Andrzej Sapkowski" || x.Books.Contains("The Witcher"))
	.OfType<Author>()
	.ToList();

Remarks

Information

Indexes are updated automatically when related documents change.

Warning

Using the LoadDocument adds a loaded document to the tracking list. This may cause very expensive calculations to occur, especially when multiple documents are tracking the same document.