Недавно я создал собственный TokenFilter для разделения существующих токенов, которые CamelCased
, на отдельные дополнительные токены.Например, фраза MyClassName
приведет к следующим 4 токенам: MyClassName
, My
, Class
, Name
Вот код:
private class CamelCaseFilter extends TokenFilter {
private final CharTermAttribute termAttribute = addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAttribute = addAttribute(OffsetAttribute.class);
private final PositionIncrementAttribute posIncAttribute = addAttribute(PositionIncrementAttribute.class);
private boolean processing;
private int processingIndex;
private int processingCharPos;
private String[] splittedValues;
protected CamelCaseFilter(TokenStream input) {
super(input);
}
@Override
public boolean incrementToken() throws IOException {
if (!processing) {
if (!input.incrementToken()) {
return false;
}
posIncAttribute.setPositionIncrement(1);
splittedValues = splitCamelCase(termAttribute.toString());
if (splittedValues.length > 1) {
processing = true;
processingIndex = 0;
processingCharPos = 0;
}
return true;
}
String part = splittedValues[processingIndex];
termAttribute.setEmpty();
termAttribute.append(part);
offsetAttribute.setOffset(processingCharPos, processingCharPos + part.length());
processingCharPos += part.length();
processingIndex++;
if (processingIndex >= splittedValues.length) {
processing = false;
}
return true;
}
private static String[] splitCamelCase(String s) {
// TODO maybe replace with splitByCharacterTypeCamelCase from commons?
// http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/StringUtils.html#splitByCharacterTypeCamelCase%28java.lang.String%29
return s.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z0-9])");
}
}
Мой вопрос, если правильно (и необходимо) использовать PositionIncrementAttribute
, как это.Документация гласит:
Определяет позицию этого токена относительно предыдущего токена в TokenStream, используемого при поиске фразы.
Значение по умолчанию равно единице..
Вот некоторые из наиболее распространенных вариантов использования:
- Установите его в ноль, чтобы поместить несколько терминов в одну и ту же позицию.Это полезно, если, например, слово имеет несколько основ.Поиск фраз, включая любой ствол, будет совпадать.В этом случае все, кроме первого приращения ствола, должны быть установлены в ноль: приращение первого экземпляра должно быть равным единице.Повторение токена с нулевым приращением также можно использовать для увеличения количества совпадений на этом токене.
- ...
Однако это не совсем так.соответствует мой случай использования. Другая часть также говорит:
Обратите внимание, что фильтр, отфильтровывающий токены, должен увеличивать приращение позиции, чтобы не генерировать поврежденные графики токенов.
В моем случае я не удаляю, а добавляю токены.Поскольку я сохраняю исходный термин, но дополнительно сохраняю его части, я подумал, что установка позиционного приращения на ноль была бы важной, чтобы не оказывать негативного влияния на поиск путем добавления новых токенов.Это действительно так, или я ошибся?