J’essaie d’utiliser Apache Lucene pour la segmentation et je suis dérouté par le processus pour obtenir des jetons à partir d’un TokenStream
.
Le pire est que je regarde les commentaires dans les JavaDocs qui traitent de ma question.
http://lucene.apache.org/java/3_0_1/api/core/org/apache/lucene/analysis/TokenStream.html#incrementToken%28%29
D’une manière ou d’une autre, un AtsortingbuteSource
est censé être utilisé, plutôt que des Token
. Je suis totalement perdu.
Quelqu’un peut-il expliquer comment obtenir des informations de type jeton depuis un TokenStream?
Oui, c’est un peu compliqué (par rapport au bon vieux), mais ça devrait le faire:
TokenStream tokenStream = analyzer.tokenStream(fieldName, reader); OffsetAtsortingbute offsetAtsortingbute = tokenStream.getAtsortingbute(OffsetAtsortingbute.class); TermAtsortingbute termAtsortingbute = tokenStream.getAtsortingbute(TermAtsortingbute.class); while (tokenStream.incrementToken()) { int startOffset = offsetAtsortingbute.startOffset(); int endOffset = offsetAtsortingbute.endOffset(); Ssortingng term = termAtsortingbute.term(); }
Selon Donotello, TermAtsortingbute
a été déconseillé en faveur de CharTermAtsortingbute
. Selon jpountz (et la documentation de Lucene), addAtsortingbute
est plus souhaitable que getAtsortingbute
.
TokenStream tokenStream = analyzer.tokenStream(fieldName, reader); OffsetAtsortingbute offsetAtsortingbute = tokenStream.addAtsortingbute(OffsetAtsortingbute.class); CharTermAtsortingbute charTermAtsortingbute = tokenStream.addAtsortingbute(CharTermAtsortingbute.class); tokenStream.reset(); while (tokenStream.incrementToken()) { int startOffset = offsetAtsortingbute.startOffset(); int endOffset = offsetAtsortingbute.endOffset(); Ssortingng term = charTermAtsortingbute.toSsortingng(); }
Voici comment cela devrait être (une version propre de la réponse d’Adam):
TokenStream stream = analyzer.tokenStream(null, new SsortingngReader(text)); CharTermAtsortingbute cattr = stream.addAtsortingbute(CharTermAtsortingbute.class); stream.reset(); while (stream.incrementToken()) { System.out.println(cattr.toSsortingng()); } stream.end(); stream.close();
Il y a deux variations dans la question OP:
Les versions récentes de la documentation de Lucene pour Token
disent:
REMARQUE: Depuis la version 2.9, il n’est plus nécessaire d’utiliser Token. Avec la nouvelle API TokenStream, elle peut être utilisée comme classe de commodité qui implémente tous les atsortingbuts, ce qui est particulièrement utile pour passer facilement de l’ancienne API TokenStream.
Et TokenStream
dit son API:
… n’est plus basé sur les jetons mais sur l’atsortingbut … la méthode préférée pour stocker les informations d’un jeton consiste à utiliser AtsortingbuteImpls.
Les autres réponses à cette question concernent le point 2 ci-dessus: comment obtenir des informations de type TokenStream
à partir d’un TokenStream
de la “nouvelle” manière recommandée en utilisant des atsortingbuts. En parcourant la documentation, les développeurs Lucene suggèrent que cette modification a été apscope en partie pour réduire le nombre d’objects individuels créés à la fois.
Mais comme certaines personnes l’ont souligné dans les commentaires de ces réponses, ils ne répondent pas directement à la question 1: comment obtenez-vous un Token
si vous voulez vraiment / avez besoin de ce type?
Avec la même modification de l’API qui fait de TokenStream
une AtsortingbuteSource
, Token
implémente désormais Atsortingbute
et peut être utilisé avec TokenStream.addAtsortingbute, tout comme les autres réponses l’indiquent pour CharTermAtsortingbute
et OffsetAtsortingbute
. Donc ils ont vraiment répondu à cette partie de la question initiale, ils ne l’ont tout simplement pas montré.
Il est important que cette approche vous permette d’accéder au Token
pendant que vous bouclez, mais il n’ya toujours qu’un seul object, quel que soit le nombre de jetons logiques présents dans le stream. Chaque appel à incrementToken()
modifiera l’état du Token
renvoyé par addAtsortingbute
; Donc, si votre objective est de créer une collection d’objects Token
différents à utiliser en dehors de la boucle, vous devrez faire un travail supplémentaire pour créer un nouvel object Token
tant que copie (profonde?).
Pour la dernière version de lucene 7.3.1
// Test the tokenizer Analyzer testAnalyzer = new CJKAnalyzer(); Ssortingng testText = "Test Tokenizer"; TokenStream ts = testAnalyzer.tokenStream("context", new SsortingngReader(testText)); OffsetAtsortingbute offsetAtt = ts.addAtsortingbute(OffsetAtsortingbute.class); try { ts.reset(); // Resets this stream to the beginning. (Required) while (ts.incrementToken()) { // Use AtsortingbuteSource.reflectAsSsortingng(boolean) // for token stream debugging. System.out.println("token: " + ts.reflectAsSsortingng(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. }
Référence: https://lucene.apache.org/core/7_3_1/core/org/apache/lucene/analysis/package-summary.html