Indexes: Extending Indexes


  • An index is defined with a mapping function that utilizes a LINQ-like syntax.

  • Writing a complex LINQ expression can be a non-trivial task.
    You can extend your indexing processing capabilities by adding custom code to the index definition.
    This will enable calling the added custom functions or using external libraries logic (e.g. NodaTime) in your LINQ expression.

  • The indexing process will execute the LINQ code and the invoked additional source code.

  • Adding this custom code can be done from Studio or from code using the additional sources feature.
    See example below.

  • Advantages:

    • Readability: Index work logic is clearer and more readable
    • Code usage: Code fragments are re-used
    • Performance: Using the additional source feature can perform better then complex LINQ expressions
    • Extendability: External libraries can be included and used


Including additional sources from client code

  • additionalSources is a field of the AbstractIndexCreationTask class.
  • It should be defined in your index class constructor which derives from AbstractIndexCreationTask.
  • Example:

class People_ByEmail extends AbstractIndexCreationTask {
    constructor() {
        super();

        this.map = "docs.People.Select(person => new { " +
            "    Email = PeopleUtil.CalculatePersonEmail(person.Name, person.Age) " +
            "})";

        this.additionalSources = 
                { 
                    "PeopleUtil":  `using System; 
                                  using NodaTime; /* using an external library */ 
                                  using static Raven.Documentation.Samples.Indexes.PeopleUtil; 
                                  namespace Raven.Documentation.Samples.Indexes 
                                  { 
                                      public static class PeopleUtil 
                                      { 
                                          public static string CalculatePersonEmail(string name, uint age) 
                                          { 
                                              return $"{name}.{Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime()) 
                                                              .ToDateTimeUtc().Year - age}@ayende.com"; 
                                          } 
                                      } 
                                  }`
                };
    }
}

Note: Deploying External DLLs

  • External DLLs that are referenced must be manually deployed to the folder containing the Raven.Server executable.