Indexing Related Documents
To extend indexing capabilities and simplify many scenarios, we have introduced the possibility to index related documents.
For start, let's consider a simple Customer - Invoice
scenario where you want to lookup for an Invoice
by Customer Name
.
public class Invoice
{
public string Id { get; set; }
public string CustomerId { get; set; }
}
public class Customer
{
public string Id { get; set; }
public string Name { get; set; }
}
Without this feature, the index that had to be created would be a fairly complex multiple map-reduce index and this is why the LoadDocument
function was introduced.
public class SampleIndex : AbstractIndexCreationTask<Invoice>
{
public SampleIndex()
{
Map = invoices => from invoice in invoices
select new
{
CustomerId = invoice.CustomerId,
CustomerName = LoadDocument<Customer>(invoice.CustomerId).Name
};
}
}
Alternative way is to use PutIndex
command:
store.DatabaseCommands.PutIndex("SampleIndex", new IndexDefinition
{
Map = @"from invoice in docs.Invoices
select new
{
CustomerId = invoice.CustomerId,
CustomerName = LoadDocument(invoice.CustomerId).Name
}"
});
Now we will be able to search for invoices using Customer Name
as a parameter.
Our next scenario will show us that indexing more complex relationships is also trivial. Lets consider a 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 to create it as follows:
public class AnotherIndex : AbstractIndexCreationTask<Author>
{
public AnotherIndex()
{
Map = authors => from author in authors
select new
{
Name = author.Name,
Books = author.BookIds.Select(x => LoadDocument<Book>(x).Name)
};
}
}
or
store.DatabaseCommands.PutIndex("AnotherIndex", new IndexDefinition
{
Map = @"from author in docs.Authors
select new
{
Name = author.Name,
Books = author.BookIds.Select(x => LoadDocument(x).Id)
}"
});
Note
Indexes will be updated automatically when related documents will change.
Note
Using LoadDocument
adds a loaded document to tracking list. This may cause very expensive calculations to occur especially when multiple documents are tracking the same document.