Implementing your own search provider

To implement the search, one there’re 2 public interfaces, implementation of which has to be registered via dependency injection during CMS startup – ISearchProvider for executing queries and ISearchIndexUpdater to listen to the global events that would require index update, such as a user requesting an index rebuild, adding/removing languages and evens of search document sources being added/removed:

namespace Composite.Search
{
    public interface ISearchProvider
    {
        Task<SearchResult> SearchAsync(SearchQuery query);
    }
    public interface ISearchIndexUpdater
    {
        void Rebuild();
        void Populate(string searchDocumentSource);
        void Remove(string searchDocumentSource);
        void CreateCollection(CultureInfo cultureInfo);
        void DropCollection(CultureInfo cultureInfo);
        void StopProcessingUpdates();
    }
}

As a starting point, we would recommend into looking into the Orckestra.Search.LuceneNET package, which source is available online .

The Orckestra.Seach.dll contains a simple file based index updates queueing mechanism and can be reused for custom search providers. The Orckestra.Seach.LuceneNET.dll only has to register an implementation ISearchProvider and an implementation of Orckestra.Search.ISearchIndex interface that is a simpler interface for indexing:

namespace Orckestra.Search
{
    public interface ISearchIndex
    {
        void Initialize(CancellationToken cancellationToken);
        void RebuildAll(); 
        void PopulateCollection(CultureInfo culture);
        void PopulateDocumentsFromSource(string documentSourceName);
        void DropCollection(CultureInfo culture);
        void DeleteDocumentsBySource(string documentSourceName);
        void AddDocument(CultureInfo cultureInfo, SearchDocument document);
        void UpdateDocument(CultureInfo cultureInfo, SearchDocument document);
        void RemoveDocument(CultureInfo cultureInfo, string documentId);
    }
}

namespace Orckestra.Search.LuceneNET
{
    [ApplicationStartup(AbortStartupOnException = true)]
    public class StartupHandler
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(typeof(ISearchIndex), typeof(LuceneSearchIndex));
            services.AddSingleton(typeof(ISearchProvider), typeof(LuceneSearchProvider));
        }

        public void OnBeforeInitialize() {}

        public void OnInitialized() {}
    }
}