Есть ли способ удалить ВСЕ специальные символы, используя фильтры Lucene? - PullRequest
0 голосов
/ 07 апреля 2020

Стандартный анализатор удаляет специальные символы, но не все из них (например: '-'). Я хочу проиндексировать мою строку, используя только буквы алфавита c, но ссылаясь на исходный документ.

Пример: 'do c -size type' должен быть проиндексирован как 'docsize' и 'type' и оба следует указать на исходный документ: 'do c -size type'

1 Ответ

0 голосов
/ 07 апреля 2020

Это зависит от того, что вы подразумеваете под «специальными символами», и от того, какие другие требования вы можете иметь. Но следующее может дать вам то, что вам нужно, или указать правильное направление.

Все следующие примеры предполагают версию Lucene 8.4.1.

Basi c Пример

Начиная с очень точного c примера, который вы привели, где doc-size type должен быть проиндексирован как docsize и type, вот специальный анализатор:

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.WhitespaceTokenizer;
import org.apache.lucene.analysis.pattern.PatternReplaceFilter;
import java.util.regex.Pattern;

public class MyAnalyzer extends Analyzer {

    @Override
    protected TokenStreamComponents createComponents(String fieldName) {
        final Tokenizer source = new WhitespaceTokenizer();
        TokenStream tokenStream = source;
        Pattern p = Pattern.compile("\\-");
        boolean replaceAll = Boolean.TRUE;
        tokenStream = new PatternReplaceFilter(tokenStream, p, "", replaceAll);
        return new TokenStreamComponents(source, tokenStream);
    }  
}

Это разбивает на пробельные символы, а затем удаляет дефисы, используя PatternReplaceFilter. Это работает, как показано ниже (я использую 「и」 в качестве разделителей, чтобы показать, где пробелы могут быть частью входов / выходов):

Input text:
「doc-size type」

Output tokens:
「docsize」
「type」

ПРИМЕЧАНИЕ - это удалит все дефисы, которые стандартная клавиатура дефисы, но не такие вещи, как тире, тире и т. д. Эти стандартные дефисы будут удалены независимо от того, где они появляются в тексте (слова начинаются, слова заканчиваются сами по себе и т. Д. c).

Набор знаков препинания

Вы можете при необходимости измените шаблон, чтобы охватить больше знаков препинания, например:

Pattern p = Pattern.compile("[$^-]");

. Это делает следующее:

Input text:
「doc-size type $foo^bar」

Output tokens:
「docsize」
「type」
「foobar」

Все, что не является символом или Di git

Вы можете использовать следующее, чтобы удалить все, что не является символом или ди git:

Pattern p = Pattern.compile("[^A-Za-z0-9]");

Это делает следующее:

Input text:
「doc-size 123 %^&*{} type $foo^bar」

Output tokens:
「docsize」
「123」
「」
「type」
「foobar」

Обратите внимание, что это имеет одна пустая строка в результирующих тегах.

ПРЕДУПРЕЖДЕНИЕ: сработает ли вышеизложенное для вас, во многом зависит от ваших конкретных c, подробных требований. Например, вам может потребоваться выполнить дополнительные преобразования для обработки различий в верхнем / нижнем регистре, т. Е. Обычные вещи, которые обычно необходимо учитывать при индексировании текста.

Примечание по стандартному анализатору

The StandardAnalyzer фактически действительно удаляет дефисы в словах (с некоторыми неясными исключениями). В своем вопросе вы упомянули, что он их не удаляет. Стандартный анализатор использует стандартный токенизатор. А стандартный токенизатор реализует правила Word Break из алгоритма сегментации текста Unicode, как указано здесь . Есть раздел, в котором обсуждается, как обрабатываются дефисы в словах.

Итак, Стандартный анализатор сделает это:

Input text:
「doc-size type」

Output tokens:
「doc」
「size」
「type」

Это должно работать как с поиском по doc, так и doctype - вопрос лишь в том, работает ли он достаточно хорошо для ваших нужд.

Я понимаю, что это может быть не тем, что вы хотите. Но если вам не придется создавать собственный анализатор, жизнь, вероятно, будет намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...