Lucene, релевантность / оценка для строки в памяти

#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;
    }
}