Sevak_Avet
@Sevak_Avet
Java/Android

Можно ли с помощью Apache Lucene определить, входит ли какая-то строка из набора в текст?

Здравствуйте!
Стоит такая задача: есть список слов (например, ["мама", "дом", "семья"]), а так же есть тексты ("Я живу у мамы", "В доме было холодно", и т.д.). Нужно определить, встречается ли в указанных текстах какое-либо слово из списка. Например, в первом тексте есть слово "мамы", если приведем его к исходной форме ("мама"), то увидим, что оно содержится в исходном списке, так же со вторым предложением. Поможет ли мне в этом деле Apache Lucene? Ну или какая-нибудь другая библиотека на Java, которая справится с поставленной задачей
  • Вопрос задан
  • 549 просмотров
Решения вопроса 2
@bobzer
Java EE Developer
Вот работающий пример поиска по неточному вхождению:
public static void main(String[] args) throws Exception {
        String fieldName = "myField";

        //создание тестового индекса
        Directory directory = new RAMDirectory();//в "настоящей" Системе здесь должно быть FSDirectory.open(dir)
        RussianAnalyzer analyzer = new RussianAnalyzer(Version.LUCENE_46);
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_46, analyzer);
        IndexWriter writer = new IndexWriter(directory, config);
        writer.addDocument(createDocument(fieldName, "Я живу у мамы"));
        writer.addDocument(createDocument(fieldName, "В доме было холодно"));
        writer.commit();
        writer.close();

        //поиск
        int startFrom = 0;
        int pageSize = 20;
        DirectoryReader ireader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(ireader);
        //FuzzyQuery осуществляет поиск неточных вхождений
        FuzzyQuery wildcardQuery = new FuzzyQuery(new Term(fieldName, "мама"));
        TopDocs topDocs = indexSearcher.search(wildcardQuery, startFrom + pageSize);
        ScoreDoc[] hits = topDocs.scoreDocs;
        for (int i = startFrom; i < topDocs.totalHits; i++) {
            if (i > (startFrom + pageSize) - 1) {
                break;
            }
            Document hitDoc = indexSearcher.doc(hits[i].doc);
            if (hitDoc != null) {
                System.out.println(hitDoc.get(fieldName));
            }
        }
    }

Часть исходников взята с серьёзной промышленной Системы, так что если что-то кажется странным, не думайте, просто используйте. Когда всё заработает "как часы", тогда вернётесь к "странностям" и поразмыслите, стоит ли переделывать...
Ответ написан
Комментировать
Sevak_Avet
@Sevak_Avet Автор вопроса
Java/Android
Нашел пока вот такое решение, которое приводит каждое слово текста в исходной форме, далее нужно только посмотреть, есть ли какое-то их слов списка в полученном результате. Но, полагаю, что это тоже можно сделать быстрее.

RussianAnalyzer analyzer = new RussianAnalyzer();
TokenStream tokenStream = analyzer.tokenStream(null, new StringReader("Я живу у мамы"));
TermAttribute termAttribute = tokenStream.getAttribute(TermAttribute.class);

while (tokenStream.incrementToken()) {
    String term = termAttribute.term();
    System.out.println(term);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы