You are currently browsing legacy 3.0 version of documentation. Click here to switch to the newest 5.1 version.
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.