Analyzers

The typical Lucene analyzers work with Elastic Search and ExamineX along with majority of the supported language analyzers.

Default analyzers

The default analyzers used in ExamineX are configured to be synonymous with the ones shipped by default in Umbraco:

  • InternalIndex: keyword_lowercase_asciifolding, this is a custom analyzer that ExamineX adds to the index which is the keyword (i.e. whitespace) analyzer with both the lowercase and asciifolding filters applied.
  • ExternalIndex: standard_asciifolding, this is a customer analyzer that Examinex adds to the index which is the lucene standard analyzer with ascii folding filters applied
  • MembersIndex: keyword_lowercase_asciifolding (as above)

It is possible to change the default analyzer used for each index:

services.Configure<ElasticSearchIndexOptions>("MembersIndex", options =>
{
    // Replace the default analyzer for the internal index to be 
    // ExamineX's whitespace_lowercase_asciifolding
    options.AnalyzerName = ExamineX.ElasticSearch.WhitespaceLowercaseAsciiFoldingAnalyzer.AnalyzerName;
});

Default field types & analyzers

It is possible to change the analyzer used per field in ExamineX in almost the same way you do in Examine, however there are slightly different field definition types for ExamineX:

  • ElasticSearchFieldDefinitionTypes.FullText - Default. The field will be indexed with the index’s default Analyzer without sortability. Generally this is fine for normal text searching.
  • ElasticSearchFieldDefinitionTypes.FullTextSortable - Will be indexed with FullText but also creates a separate backing field for performing the sorting.
  • ElasticSearchFieldDefinitionTypes.Integer - Stored as a numerical structure.
  • ElasticSearchFieldDefinitionTypes.Double - Stored as a numerical structure.
  • ElasticSearchFieldDefinitionTypes.Long - Stored as a numerical structure.
  • ElasticSearchFieldDefinitionTypes.DateTime - Stored as a DateTime.
  • ElasticSearchFieldDefinitionTypes.Raw - Will be indexed with the keyword analyzer so searching will only match with an exact value.

Set the field definition for “productPrice” to be a Double:

// Modify the options for the Internal index
services.Configure<ElasticSearchIndexOptions>("InternalIndex", options =>
{
    options.FieldDefinitions.AddOrUpdate(new FieldDefinition("productPrice", ElasticSearchFieldDefinitionTypes.Double));
});

Custom field types & analyzers

You can define custom field types in ExamineX (similar to how you would create custom field types in Examine). This is useful when you want need a custom analyzer for your fields.

Example: If you want to define a custom field type, you can do that during index composition by passing in a value to the IndexValueTypesFactory property of the ElasticSearchIndexOptions. The value for this parameter is: IReadOnlyDictionary<string, IElasticSearchFieldValueTypeFactory> indexValueTypesFactory. The dictionary Key is the name of the field type and the Value is a factory that returns a IElasticSearchFieldValueTypeFactory for a given field name. ExamineX has a default implementation of this which includes all of the above default field types. If this parameter is specified, all of ExamineX’s default field types will still be used but you can override the custom implementations if a Key that you provide matches a default implementation.

This will create a Dutch field type with a “dutch” analyzer.

// Modify the options for the Internal index
services.Configure<ElasticSearchIndexOptions>("InternalIndex", options =>
{
    // create/assign custom value types factory
    options.IndexValueTypesFactory = new Dictionary<string, IElasticSearchFieldValueTypeFactory>
    {
        ["dutchString"] =
            // define the factory
            new ElasticSearchFieldValueTypeFactory(fieldName =>
                new ElasticSearchFieldValueType(
                    fieldName,
                    FieldType.Text,
                    // Use dutch analyzer
                    ElasticSearchAnalyzerNames.Dutch))
    };

    // Assign the custom field type to the "dutchTitle" field
    options.FieldDefinitions.AddOrUpdate(
        "dutchTitle",
        s => new FieldDefinition(s, "dutchString"));

});

Events

All of the underlying Examine events are available in ExamineX such as TransformingIndexValues, IndexingError and OperationComplete.

These additional events are available in ExamineX:

ElasticSearchIndex.CreatingOrUpdatingIndex - Allows you to modify the definition of the index before it is created in Elastic Search.

It is advised to not remove any indexes, fields, or custom analyzers created with ExamineX otherwise unexpected errors may result

Customizing the Elastic Search index

Using the ElasticSearchIndex.CreatingOrUpdatingIndex can be quite powerful if you want to leverage more out of Elastic Search than what is provided by default.

An example of adding an event handler for CreatingOrUpdatingIndex:

if (examineManager.TryGetIndex("ExternalIndex", out var index) 
    && index is ElasticSearchIndex elasticIndex)
{
    elasticIndex.CreatingOrUpdatingIndex += ElasticIndex_CreatingIndex;
}