Search code examples
autocompletelucene.netautosuggest

Autosuggest / Autocomplete with multiple indexes and Lucene.Net?


Does anyone have any suggestions when it comes to building an Autosuggestion / Autocomplete search on multiple indexes?

Update: I found this link that may be how I need to approach my solution.


Solution

  • You can use a MultiReader to read from several readers. Here's an example to iterate all indexed terms in a field named "data". You specify where you want to start the enumeration in the call to .Terms(...). You could specify another starting point to match what the user has entered so far, to provide autocompletion on a term level.

    using System;
    using Lucene.Net.Analysis;
    using Lucene.Net.Documents;
    using Lucene.Net.Index;
    using Lucene.Net.Store;
    
    public static class ConsoleApp {
        private static readonly String FieldName = "data";
    
        public static void Main() {
            var ram1 = Create(prefix: "b");
            var ram2 = Create(prefix: "a");
    
            var multiReader = new MultiReader(new[] {
                IndexReader.Open(ram1, readOnly: true),
                IndexReader.Open(ram2, readOnly: true)
            });
    
            var termsEnum = multiReader.Terms(new Term(FieldName));
            do {
                var term = termsEnum.Term();
                if (term.Field() != FieldName)
                    break;
    
                Console.WriteLine(term.Text());
            } while (termsEnum.Next());
        }
    
        public static Directory Create(String prefix) {
            var dir = new RAMDirectory();
    
            var writer = new IndexWriter(dir, a: new KeywordAnalyzer(), create: true, mfl: IndexWriter.MaxFieldLength.UNLIMITED);
            for (var i = 0; i < 5; ++i) {
                var doc = new Document();
                doc.Add(new Field(FieldName, prefix + i, Field.Store.NO, Field.Index.NOT_ANALYZED));
                writer.AddDocument(doc);
            }
            writer.Close();
    
            return dir;
        }
    }