C# Java
Article For
2.0 2.5 3.0 3.5 5.1 5.2 5.3

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.