Como obter um token de um TokenStream Lucene?

Eu estou tentando usar o Apache Lucene para tokenizing, e estou confuso com o processo para obter Tokens de um TokenStream .

A pior parte é que eu estou olhando para os comentários nos JavaDocs que abordam a minha pergunta.

http://lucene.apache.org/java/3_0_1/api/core/org/apache/lucene/analysis/TokenStream.html#incrementToken%28%29

De alguma forma, uma AttributeSource deve ser usada, em vez de Token s. Eu estou totalmente em uma perda.

Alguém pode explicar como obter informações semelhantes a tokens de um TokenStream?

Sim, é um pouco complicado (comparado ao bom e velho jeito), mas isso deve ser feito:

 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(); } 

Edit: O novo caminho

De acordo com Donotello, o TermAttribute foi substituído em favor do CharTermAttribute . De acordo com o jpountz (e a documentação do Lucene), addAttribute é mais desejável que o 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(); } 

É assim que deve ser (uma versão limpa da resposta de Adam):

 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(); 

Existem duas variações na questão do OP:

  1. O que é “o processo para obter Tokens de um TokenStream”?
  2. “Alguém pode explicar como obter informações semelhantes a tokens de um TokenStream?”

Versões recentes da documentação do Lucene para Token dizem (ênfase adicionada):

NOTA: A partir do 2.9 … não é mais necessário usar o Token, com a nova API do TokenStream ele pode ser usado como class de conveniência que implementa todos os Attributes, o que é especialmente útil para alternar facilmente da antiga para a nova API do TokenStream.

E TokenStream diz sua API:

… foi movida de baseada em tokens para baseada em atributos … a maneira preferida de armazenar as informações de um token é usar AttributeImpls.

As outras respostas a essa pergunta são: # 2 acima: como obter informações semelhantes a tokens de um TokenStream na “nova” maneira recomendada de usar atributos. Ao ler a documentação, os desenvolvedores do Lucene sugerem que essa alteração foi feita, em parte, para reduzir o número de objects individuais criados por vez.

Mas como algumas pessoas apontaram nos comentários dessas respostas, elas não respondem diretamente # 1: como você obtém um Token se realmente quer / precisa desse tipo?

Com a mesma alteração de API que torna o TokenStream um AttributeSource , o Token agora implementa o Attribute e pode ser usado com o TokenStream.addAttribute, assim como as outras respostas mostram para CharTermAttribute e OffsetAttribute . Então eles realmente responderam a parte da pergunta original, eles simplesmente não mostraram.

É importante que, embora essa abordagem permita que você acesse o Token enquanto você está em loop, ele ainda é um único object, independentemente do número de tokens lógicos no stream. Cada chamada para incrementToken() irá alterar o estado do Token retornado de addAttribute ; Portanto, se seu objective é construir uma coleção de diferentes objects Token a serem usados ​​fora do loop, você precisará fazer um trabalho extra para criar um novo object Token como uma cópia (profunda).

Para a versão mais recente do 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. } 

Referência: https://lucene.apache.org/core/7_3_1/core/org/apache/lucene/analysis/package-summary.html