java – 将令牌添加到lucene tokenstream
我写了一个TokenFilter,它在流中添加了令牌.
测试表明它有效,但我不完全明白为什么. 如果有人能够阐明语义,我将不胜感激.特别是,在(*)中,恢复状态是不是意味着我们要么覆盖当前的令牌或者在捕获状态之前创建的令牌? 这大概是我做的 private final LinkedList<String> extraTokens = new LinkedList<String>(); private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); private State savedState; @Override public boolean incrementToken() throws IOException { if (!extraTokens.isEmpty()) { // Do we not loose/overwrite the current termAtt token here? (*) restoreState(savedState); termAtt.setEmpty().append(extraTokens.remove()); return true; } if (input.incrementToken()) { if (/* condition */) { extraTokens.add("fo"); savedState = captureState(); } return true; } return false; } 这是否意味着,对于空格的输入流标记字符串“a b c” (a) -> (b) -> (c) -> ... 其中bb是b的新同义词,那么在使用restoreState时,该图将被构造为这样? (a) / (b) (bb) / (c) | ... 属性 给定文本foo bar baz与fo是foo和qux的句柄是bar baz的同义词,我是否构建了正确的属性表? +--------+---------------+-----------+--------------+-----------+ | Term | startOffset | endOffset | posIncrement | posLenght | +--------+---------------+-----------+--------------+-----------+ | foo | 0 | 3 | 1 | 1 | | fo | 0 | 3 | 0 | 1 | | qux | 4 | 11 | 0 | 2 | | bar | 4 | 7 | 1 | 1 | | baz | 8 | 11 | 1 | 1 | +--------+---------------+-----------+--------------+-----------+ 解决方法
1.
基于属性的API如何工作,分析器链中的每个TokenStream都会以每次调用incrementToken()的方式修改某些Attributes的状态.你的链中的最后一个元素产生最终的令牌. 每当分析器链的客户端调用incrementToken()时,最后一个TokenStream会将某些属性的状态设置为表示下一个标记所需的任何值.如果不能这样做,它可能会在其输入上调用incrementToken(),以使之前的TokenStream工作.这一直持续到最后一个TokenStream返回false,表明没有更多的令牌可用. 一个captureState将调用TokenStream的所有属性的状态复制到一个状态,一个restoreState会覆盖每个Attribute的状态,以前被捕获的(作为一个参数给出). 令牌过滤器的工作方式是,它将调用input.incrementToken(),以便之前的TokenStream将将Attributes的状态设置为下一个令牌.然后,如果你定义的条件成立(比如说termAtt是“b”),那么它会将一个“bb”添加到一个堆栈中,将这个状态保存在某个地方并返回true,以便客户端可以使用该令牌.在incrementToken()的下一次调用中,它不会使用input.incrementToken().无论当前状态如何,它代表以前已经消耗的令牌.然后,过滤器恢复状态,使得一切都与之前完全一样,然后生成“bb”作为当前令牌并返回true,以便客户端可以使用令牌.只有在下一次呼叫时,它将(再次)从上一个过滤器中消耗下一个令牌. 这实际上不会产生您显示的图形,但在“b”之后插入“bb”,所以它是真的 (a) -> (b) -> (bb) -> (c) 那么,为什么你先把国家拯救出来呢? (a:1) -> (b:2) -> (bb:3) -> (c:4) 而你真的想要的 (a:1) — -> (b:2) -> — (c:3) / -> (bb:2) -> 因此,为了生成图形,您必须将插入的“bb”的位置增量设置为0 private final PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class); // later in incrementToken restoreState(savedState); posIncAtt.setPositionIncrement(0); termAtt.setEmpty().append(extraTokens.remove()); restoreState确保保留其他属性,如偏移,令牌类型等,并且您只需更改用例所需的其他属性. 2. 干扰器只会更改令牌,通常不会产生新的令牌,也不会更改位置增量或偏移量. +--------+---------------+-----------+--------------+-----------+ | Term | startOffset | endOffset | posIncrement | posLenght | +--------+---------------+-----------+--------------+-----------+ | fo | 0 | 3 | 1 | 1 | | qux | 4 | 11 | 1 | 2 | | bar | 4 | 7 | 0 | 1 | | baz | 8 | 11 | 1 | 1 | +--------+---------------+-----------+--------------+-----------+ 作为基本规则,对于多项同义词,“ABC”是“a b c”的同义词,您应该看到 > positionIncrement(“ABC”)> 0(第一个令牌的增量) 实际上,相同(开始|结束)位置的令牌必须具有相同的(start | end)偏移量 希望这有助于揭开一些光. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |