Как получить токен из 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
- HTML5 iFrame Бесшовный атрибут
- Атрибуты HttpPost и HttpGet в MVC: зачем использовать HttpPost?
- Получить перечисление из атрибута enum
- Как установить динамическое значение в моем атрибуте
- Сериализация XML - Отключить корневой элемент рендеринга массива
Так или иначе, предполагается, что используется AttributeSource
Source, а не Token
s. Я полностью в недоумении.
Может ли кто-нибудь объяснить, как получить токен-подобную информацию от TokenStream?
- Когда выполняется конструктор пользовательского атрибута?
- Выбор элементов по атрибуту
- Атрибут InternalsVisibleTo не работает
- Изменение типа ввода jQuery
- __ атрибут __ ((const)) vs __attribute __ ((чистый)) в GNU C
- Как удалить «onclick» с помощью JQuery?
- Рекурсия, анализ XML-файла с атрибутами в treeview c #
- Укажите несколько селекторов атрибутов в CSS
Да, это немного запутанно (по сравнению с хорошим способом), но это должно сделать это:
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(); }
Вот как это должно быть (чистая версия ответа Адама):
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();
В вопросе ОП есть два варианта:
- Что такое «процесс получения токенов из TokenStream»?
- «Кто-нибудь может объяснить, как получить токен-информацию из TokenStream?»
Последние версии документации Lucene для Token
говорят (выделено мной):
ПРИМЕЧАНИЕ. Начиная с версии 2.9 … больше не нужно использовать Token, с новым API TokenStream он может использоваться как class удобства, который реализует все атрибуты, что особенно полезно для простого перехода от старого к новому API TokenStream.
И TokenStream
говорит о своем API:
… переместился с Token-based на основе Attribute … предпочтительный способ хранения информации Token – использовать AttributeImpls.
Другие ответы на этот вопрос охватывают # 2 выше: как получить токен-подобную информацию из TokenStream
в «новом» рекомендованном способе с использованием атрибутов. Прочитав документацию, разработчики Lucene полагают, что это изменение было сделано, в частности, для уменьшения количества отдельных объектов, созданных за раз.
Но, как некоторые люди указали в комментариях к этим ответам, они не отвечают прямо на # 1: как вы получаете Token
если вы действительно хотите / нуждаетесь в этом типе?
С тем же изменением API, которое делает TokenStream
AttributeSource
TokenStream
, Token
теперь реализует Attribute
и может использоваться с TokenStream.addAttribute так же, как другие ответы показывают CharTermAttribute
и OffsetAttribute
. Поэтому они действительно ответили на эту часть первоначального вопроса, они просто не показали этого.
Важно, что, хотя этот подход позволит вам получить доступ к Token
во время цикла, он все еще остается единственным объектом независимо от того, сколько логических токенов находится в streamе. Каждый вызов incrementToken()
изменит состояние Token
возвращенного из addAttribute
; Поэтому, если ваша цель состоит в том, чтобы создать коллекцию различных объектов Token
которые будут использоваться вне цикла, вам нужно будет сделать дополнительную работу, чтобы создать новый объект Token
в виде (глубокой?) Копии.
Для последней версии lucene 7.3.1
// Test the tokenizer Analyzer testAnalyzer = new CJKAnalyzer(); String testText = "Test Tokenizer"; TokenStream ts = testAnalyzer.tokenStream("context", new StringReader(testText)); OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class); try { ts.reset(); // Resets this stream to the beginning. (Required) while (ts.incrementToken()) { // Use AttributeSource.reflectAsString(boolean) // for token stream debugging. System.out.println("token: " + ts.reflectAsString(true)); System.out.println("token start offset: " + offsetAtt.startOffset()); System.out.println(" token end offset: " + offsetAtt.endOffset()); } ts.end(); // Perform end-of-stream operations, eg set the final offset. } finally { ts.close(); // Release resources associated with this stream. }
Ссылка: https://lucene.apache.org/core/7_3_1/core/org/apache/lucene/analysis/package-summary.html