How to create a FieldIndexHandler

From Sense/Net Wiki
Jump to: navigation, search
  •  
  •  
  •  
  •  
  • 100%
  • 6.0
  • Enterprise
  • Community
  • Planned

Overview

Sense/Net supports per-Field indexing meaning that individual Field data is indexed, and indexing of every Field can be configured separately. Besided using the built-in index handler types (see Field Indexing#IndexHandler) it is supported to create custom index handlers. This article shows an example on how to create a custom Field index handler.

Steps

In this section I will show you how to create and use a new FieldIndexHandler class step-by-step. We will create a handler that splits up Field data along commas and semicolons and use it in the demo Car Content.

1. Create a new class

2. Implement the new class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SenseNet.Search;
using Lucene.Net.Documents;
 
namespace SensenetKustomizers.IndexingDemo
{
    // IndexHandler for comma or semicolon separated strings (e.g. Red,Green,Blue)
    public class CommaOrSemicolonSeparatedIndexHandler : IndexHandler, IIndexValueConverter<string>
    {
        // Returns the value if the field is stored.
        public string GetBack(string lucFieldValue)
        {
            // Return without any conversion.
            return lucFieldValue;
        }
 
        // Parses a value.
        public override bool TryParseAndSet(SenseNet.Search.Parser.QueryFieldValue value)
        {
            // Set the parsed value.
            value.Set(value.StringValue.ToLower());
            // Successful.
            return true;
        }
 
        // Produces the desired index field(s). 
        public override IEnumerable<AbstractField> GetIndexFields(SenseNet.ContentRepository.Field snField, out string textExtract)
        {
            // Ensure initial textExtract for out parameter. It is used if the field value is null or empty.
            textExtract = String.Empty;
            // Get the value. A field type is indexable with this handler that provides a string value but ShortText and LongText are recommended.
            var snFieldValue = (string)snField.GetData();
            // Return null if the value is not indexable. Lucene field and text extract won't be created.
            if (String.IsNullOrEmpty(snFieldValue))
                return null;
            // Convert to lowercase for case insensitive index handling
            snFieldValue = snFieldValue.ToLower();
            // Create an array of words. Words can be separated by comma or semicolon. Whitespaces will be removed.
            var terms = snFieldValue.Split(",;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(w => w.Trim()).ToArray();
            // Concatenate the words with space separator for text extract.
            textExtract = String.Join(" ", terms);
            // Produce the lucene multiterm field with a base's tool and return with it.
            return CreateField(snField.Name, terms);
        }
    }
}

3. Define a Field using the new FieldIndexHandler

  • Go to Explore
  • Navigate to /Root/System/Schema/ContentTypes/GenericContent/ListItem/Car and Edit the CTD
  • Append the following field declaration into the Fields element (simple long text field that is bound the new field index handler):
<Field name="Passengers" type="LongText">
  <Indexing>
	<IndexHandler>SensenetKustomizers.IndexingDemo.CommaOrSemicolonSeparatedIndexHandler</IndexHandler>
  </Indexing>
</Field>
  • Save.

4. Create a demo Car Content to test the feature

  • Navigate to /Root/YourContents.
  • Create a new Car content.
  • Fill the form:
		Uri name:   Trabant
		Name:       Trabant
		Make:       Trabant
		Passengers: Joe, John, Henry, Tom
  • Save

5. Go to search and test queries

		Type:Car AND Passengers:John
  • Check the result:
		Trabant  /Root/YourContents/Trabant

6. Test the right syntax

  • (the new field index handler splits the input and creates a multi term Lucene field)
  • Type into the textarea:
		Type:Car AND Passengers:(Joe John)
  • Check the result:
		Trabant  /Root/YourContents/Trabant

7. Validate the function

  • Type into the textarea:
		Type:Car
  • Check the result (all Car Content should turn up):
		Trabant  /Root/YourContents/Trabant

Video

Related links

References