Я бы хотел реализовать поисковый индекс, используя Lucene. Net 4.8, который предоставляет пользователю предложения / автозаполнение для отдельных слов и фраз.
Индекс был успешно создан; предложения, где я остановился.
Версия 4.8, кажется, внесла значительное количество критических изменений, и ни один из доступных примеров, которые я нашел, не работал.
Где я стою
Для справки, LuceneVersion
это:
private readonly LuceneVersion LuceneVersion = LuceneVersion.LUCENE_48;
Решение 1
Я пробовал это , но не могу пройти reader.Terms
:
public void TryAutoComplete()
{
var analyzer = new EnglishAnalyzer(LuceneVersion);
var config = new IndexWriterConfig(LuceneVersion, analyzer);
RAMDirectory dir = new RAMDirectory();
using (IndexWriter iw = new IndexWriter(dir, config))
{
Document d = new Document();
TextField f = new TextField("text","",Field.Store.YES);
d.Add(f);
f.SetStringValue("abc");
iw.AddDocument(d);
f.SetStringValue("colorado");
iw.AddDocument(d);
f.SetStringValue("coloring book");
iw.AddDocument(d);
iw.Commit();
using (IndexReader reader = iw.GetReader(false))
{
TermEnum terms = reader.Terms(new Term("text", "co"));
int maxSuggestsCpt = 0;
// will print:
// colorado
// coloring book
do
{
Console.WriteLine(terms.Term.Text);
maxSuggestsCpt++;
if (maxSuggestsCpt >= 5)
break;
}
while (terms.Next() && terms.Term.Text.StartsWith("co"));
}
}
}
reader.Terms
больше не существует . Будучи новичком в Lucene, неясно, как это изменить.
Решение 2
Попытка этого , мне выдается ошибка:
public void TryAutoComplete2()
{
using(var analyzer = new EnglishAnalyzer(LuceneVersion))
{
IndexWriterConfig config = new IndexWriterConfig(LuceneVersion, analyzer);
RAMDirectory dir = new RAMDirectory();
using(var iw = new IndexWriter(dir,config))
{
Document d = new Document()
{
new TextField("text", "this is a document with a some words",Field.Store.YES),
new Int32Field("id", 42, Field.Store.YES)
};
iw.AddDocument(d);
iw.Commit();
using (IndexReader reader = iw.GetReader(false))
using (SpellChecker speller = new SpellChecker(new RAMDirectory()))
{
//ERROR HERE!!!
speller.IndexDictionary(new LuceneDictionary(reader, "text"), config, false);
string[] suggestions = speller.SuggestSimilar("dcument", 5);
IndexSearcher searcher = new IndexSearcher(reader);
foreach (string suggestion in suggestions)
{
TopDocs docs = searcher.Search(new TermQuery(new Term("text", suggestion)), null, Int32.MaxValue);
foreach (var doc in docs.ScoreDocs)
{
System.Diagnostics.Debug.WriteLine(searcher.Doc(doc.Doc).Get("id"));
}
}
}
}
}
}
При отладке speller.IndexDictionary(new LuceneDictionary(reader, "text"), config, false);
выдает ошибку The object cannot be set twice!
, которую я не могу объяснить.
Любые мысли приветствуются.
Уточнение
Я хотел бы вернуть список предлагаемых терминов для данного ввода, а не документы или их полное содержание.
Например, если документ содержит «Здравствуйте, меня зовут Кларк. Я из Атланты», и я отправляю «Atl», тогда «Атланта» должна вернуться в качестве предложения.