#lucene #full-text-search
#lucene #полнотекстовый поиск
Вопрос:
Я создаю бота, который отслеживает HN по темам, которые меня интересуют.
Я хотел бы проанализировать строку в памяти и определить, содержит ли она некоторые ключевые слова, которые меня интересуют.
Я бы хотел, чтобы он учитывал то, что Lucene делает при выполнении стандартного запроса (выделение слов, стоп-слова, нормализация пунктуации и т.д.).
Вероятно, я мог бы создать индекс в памяти и запросить его, используя обычный подход, но есть ли способ, которым я могу использовать внутренние компоненты Lucene, чтобы избежать создания ненужного индекса?
Бонусные баллы, если я смогу получить значение релевантности (0.0-1.0) вместо простого значения true / false.
Псевдокод:
public static decimal IsRelevant(string keywords, string input)
{
// Does the "input" variable look like it contains "keywords"?
}
IsRelevant("books", "I just bought a book, and I like it."); // matching!
IsRelevant("book", "I just bought many books!"); // matching!
Ответ №1:
Я создал решение, используя индекс поиска в памяти. Это не идеально, но оно выполняет задачу.
public static float RelevanceScore(string keyword, string input)
{
var directory = new RAMDirectory();
var analyzer = new EnglishAnalyzer(LuceneVersion.LUCENE_48);
using (var writer = new IndexWriter(directory, new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer)))
{
var doc = new Document();
doc.Add(new Field("input", input, Field.Store.YES, Field.Index.ANALYZED));
writer.AddDocument(doc);
writer.Commit();
}
using (var reader = IndexReader.Open(directory))
{
var searcher = new IndexSearcher(reader);
var parser = new QueryParser(LuceneVersion.LUCENE_48, "input", analyzer);
var query = parser.Parse(keyword);
var result = searcher.Search(query, null, 10);
if (result.ScoreDocs.Length == 0)
{
return 0;
}
var doc = result.ScoreDocs.Single();
return doc.Score;
}
}