You are currently browsing legacy 4.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

Indexes: Indexing Related Documents

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

Example I

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

Without this feature, you would have to create a fairly complex multiple map-reduce index. This is why the LoadDocument function was introduced.

class Products_ByCategoryName extends AbstractIndexCreationTask {
    constructor() {
        super(); = `docs.Products.Select(product => new {     
            CategoryName = (this.LoadDocument(product.Category, "Categories")).Name 
const indexDefinition = new IndexDefinition(); = "Products/ByCategoryName";
indexDefinition.maps = new Set([
    `from product in products    
     select new {        
         CategoryName = LoadDocument(product.Category, ""Categories"").name    

await store.maintenance.send(new PutIndexesOperation(indexDefinition));

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

const results = session
    .query({ indexName: "Products/ByCategoryName" })
    .whereEquals("CategoryName", "Beverages")

Example II

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

class Book {
    constructor(id, name) { = id; = name;

class Author {
    constructor(id, name, bookIds) { = id; = name;
        this.bookIds = bookIds;

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

class Authors_ByNameAndBooks extends AbstractIndexCreationTask {
    constructor() {
        super(); = `docs.Authors.Select(author => new {     
            name =,     
            books = author.bookIds.Select(x => (this.LoadDocument(x, "Books")).name) 

const indexDefinition = new IndexDefinition(); = "Authors/ByNameAndBooks";
indexDefinition.maps = new Set([
    `from author in docs.Authors      
     select new 
         name =,          
         books = author.bookIds.Select(x => LoadDocument(x, ""Books"").id)      

await store.maintenance.send(new PutIndexesOperation(indexDefinition));

const results = await session
    .query({ indexName: "Authors/ByNameAndBooks" })
    .whereEquals("name", "Andrzej Sapkowski")
    .whereEquals("books", "The Witcher")



Indexes are updated automatically when related documents change.


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.