简体   繁体   中英

How to register lucene in dependency injection?

I am having trouble to find information about registering the different building blocks of Lucene into the dependency injection. I am also not sure about the lifetimes.

I think one should reuse the IndexWriter as it seems to be costly. And i managed to do so.

But when it comes to search im lost. Should i have DI handle the IndexReader or the LuceneDictionary as well as the AnalyzingInfixSuggester? And how could this be done.

This is how i went for now:

Registration:

 public static IServiceCollection AddLucene(this IServiceCollection services)
 {
     var version = Lucene.Net.Util.LuceneVersion.LUCENE_48;
     var directory = new RAMDirectory();
     var analyzer = new StandardAnalyzer(version);
     var config = new IndexWriterConfig(version, analyzer);
     var writer = new IndexWriter(directory, config);

     services.AddSingleton(writer);
     services.AddSingleton(analyzer);
     services.AddSingleton(directory);

     services.AddTransient<SearchService>();
     services.AddTransient<IndexService>();
        
     return services;
 }

IndexWriter:

    public IndexService(IndexWriter writer)
    { 
        _writer = writer;
    }

    public void WriteIndex()
    {        
        var searchResults = QueryDatabase();
        
        var idField = new StringField(nameof(SearchResult.DatabaseId), "", Field.Store.YES);
        var headField = new StringField(nameof(SearchResult.Header), "", Field.Store.YES);
        var bodyField = new TextField(nameof(SearchResult.Body), "", Field.Store.YES);
        var typeField = new TextField(nameof(SearchResult.Type), "", Field.Store.YES);

        var doc = new Document
        {
            idField,
            headField,
            bodyField,
            typeField
        };

        foreach (var result in searchResults)
        {
            idField.SetStringValue(result.DatabaseId);
            headField.SetStringValue(result.Header);
            bodyField.SetStringValue(result.Body);
            typeField.SetStringValue(result.Type);
            _writer.AddDocument(doc);
        }
        _writer.Commit();
    }

Search:

    public SearchService(StandardAnalyzer analyzer, RAMDirectory directory)
    { 
        _analyzer = analyzer;
        _directory = directory;
    }

    public SearchResponse Search(string input, int page)
    { 
        var reader = DirectoryReader.Open(_directory);
        var searcher = new IndexSearcher(reader);

        var multiFieldQP = new MultiFieldQueryParser(LuceneVersion.LUCENE_48, _searchFields, _analyzer);
        var _input = EscapeSearchTerm(input.Trim());
        var query = multiFieldQP.Parse(_input);

        var docs = searcher.Search(query, null, 1000).ScoreDocs;
        ...
    }

    public List<string> SearchAhead(string input)
    {
        var reader = DirectoryReader.Open(_directory);
        var dictionary = new LuceneDictionary(reader, nameof(SearchResult.Header));

        using var analyzingSuggester = 
            new AnalyzingInfixSuggester(LuceneVersion.LUCENE_48, new RAMDirectory(), _analyzer);

        analyzingSuggester.Build(dictionary);
        var lookupResultList = analyzingSuggester.DoLookup(input.Trim(), false, 9);
        ...
    }

Most of this code is based on https://beckshome.com/2022/11/lucene-blazor-part-3-auto-complete and i modified it to work with asp.net core api.

It is an interesting question but for me I only use dependency injection if I have multiple types of the dependency that I might chose to use and it's important to be able to swap out those types system wide easily.

So that is to say I didn't personally put any aspects of Lucene in my DI container.

You could of course registering the IndexWriter as a singleton if you are using NRT (Near REAL TIME) readers.

But that only makes sense if you are using Lucene.NET to manage a single index. Otherwise you'd probably need to wrap that IndexWriter in a custom type that helps you know which index it's a writer for. Then that custom type could be registered in DI as a singleton and provide static access to the associated IndexWriter .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM