Как получить токен из Lucene TokenStream?
Я пытаюсь использовать Apache Lucene для токенизации, и я сбиваю с толку на процесс получения токенов с TokenStream
.
Хуже всего то, что я смотрю комментарии в JavaDocs, которые затрагивают мой вопрос.
http://lucene.apache.org/java/3_0_1/api/core/org/apache/lucene/analysis/TokenStream.html#incrementToken%28%29
Как-то предполагается, что используется AttributeSource
, а не Token
s. Я полностью в недоумении.
Может кто-нибудь объяснить, как получить токен-подобную информацию из TokenStream?
Ответы
Ответ 1
Да, это немного запутанное (по сравнению с хорошим способом), но это должно сделать это:
TokenStream tokenStream = analyzer.tokenStream(fieldName, reader);
OffsetAttribute offsetAttribute = tokenStream.getAttribute(OffsetAttribute.class);
TermAttribute termAttribute = tokenStream.getAttribute(TermAttribute.class);
while (tokenStream.incrementToken()) {
int startOffset = offsetAttribute.startOffset();
int endOffset = offsetAttribute.endOffset();
String term = termAttribute.term();
}
Изменить: Новый способ
По словам Донотелло, TermAttribute
устарел в пользу CharTermAttribute
. Согласно jpountz (и документации Lucene), addAttribute
более желательно, чем getAttribute
.
TokenStream tokenStream = analyzer.tokenStream(fieldName, reader);
OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while (tokenStream.incrementToken()) {
int startOffset = offsetAttribute.startOffset();
int endOffset = offsetAttribute.endOffset();
String term = charTermAttribute.toString();
}
Ответ 2
Вот как это должно быть (чистая версия Адама отвечает):
TokenStream stream = analyzer.tokenStream(null, new StringReader(text));
CharTermAttribute cattr = stream.addAttribute(CharTermAttribute.class);
stream.reset();
while (stream.incrementToken()) {
System.out.println(cattr.toString());
}
stream.end();
stream.close();
Ответ 3
В вопросе OP есть два варианта:
- Что такое "процесс получения токенов из TokenStream"?
- "Кто-нибудь может объяснить, как получить токен-информацию из TokenStream?"
Последние версии Документация Lucene для Token
говорят (выделено мной):
ПРИМЕЧАНИЕ. Начиная с версии 2.9... не требуется больше использовать токен, а новый API TokenStream можно использовать как класс удобства, который реализует все атрибуты, что особенно полезно для переход от старого к новому API TokenStream.
И TokenStream
говорит о своем API:
... переместился с Token-based на основе Attribute... предпочтительным способом хранения информации Token является использование AttributeImpls.
Другие ответы на этот вопрос охватывают # 2 выше: как получить токен-подобную информацию из TokenStream
в "новом" рекомендованном способе с использованием атрибутов. Прочитав документацию, разработчики Lucene полагают, что это изменение было сделано, в частности, для уменьшения количества отдельных объектов, созданных за раз.
Но, как некоторые люди указали в комментариях к этим ответам, они прямо не отвечают # 1: как вы получаете Token
, если вы действительно хотите/нуждаетесь в этом типе?
С тем же API-изменением, которое делает TokenStream
a AttributeSource
, Token
теперь реализует Attribute
и может использоваться с TokenStream.addAttribute, как и другие ответы для CharTermAttribute
и OffsetAttribute
. Поэтому они действительно ответили на эту часть оригинального вопроса, они просто не показали этого.
Важно, что, хотя этот подход позволит вам получить доступ к Token
во время цикла, это все еще только один объект, независимо от того, сколько логических токенов находится в потоке. Каждый вызов incrementToken()
изменяет состояние Token
, возвращаемое с addAttribute
; Поэтому, если ваша цель состоит в создании коллекции из разных Token
объектов, которые будут использоваться вне цикла, вам нужно будет сделать дополнительную работу, чтобы сделать новый Token
объект как (глубокий?) копия.