当前位置: 首页 > 知识库问答 >
问题:

向lucene tokenstream添加令牌

宇文航
2023-03-14

我编写了一个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)    (bb)
   \   /
    (c)
     |
    ...

假定文本foo bar baz,其中fofoo的词干,quxbar 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个答案

夹谷腾
2023-03-14

1.

基于属性的API的工作原理是,在每次调用incrementToken()时,分析器链中的每个TokenStream都会以某种方式修改某个Attribute的状态。然后链中的最后一个元素产生最后的令牌。

每当分析器链的客户端调用incrementToken()时,最后一个TokenStream会将某个属性的状态设置为表示下一个令牌所需的任何状态。如果不能这样做,它可以在其输入上调用incrementToken(),让前面的TokenStream执行其工作。这一直持续到最后一个tokenstream返回false,这表明没有更多的标记可用。

这实际上不会产生您所显示的图形,而是在“b”之后插入“bb”,所以它实际上是

(a) -> (b) -> (bb) -> (c)

那么,你为什么首先要拯救国家呢?在生成令牌时,您要确保短语查询或高亮显示能够正确工作。当文本“a b c”“bb”“b”的同义词时,您会期望短语query“b c”以及“bb c”起作用。你必须告诉html" target="_blank">索引,“B”和“BB”都在相同的位置。Lucene为此使用了一个位置增量,默认情况下,位置增量为1,这意味着每个新的令牌(读取、调用incrementToken())都在前一个令牌之后1个位置。所以,对于最终的位置,产生的流是

(a:1) -> (b:2) -> (bb:3) -> (c:4)

当你真的想

(a:1) — -> (b:2)  -> — (c:3)
      \              /
        -> (bb:2) ->
private final PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class);
// later in incrementToken
restoreState(savedState);
posIncAtt.setPositionIncrement(0);
termAtt.setEmpty().append(extraTokens.remove());

2.

一个stemmer只改变令牌,它通常不会产生新的令牌,也不会改变位置增量或偏移量。此外,由于位置增量意味着当前术语应该出现在PositionIncrement位置之后,因此QUX的增量应该为1,因为它是之后的下一个标记,而Bar的增量应该为0,因为它与QUX位于相同的位置。桌子宁愿看起来像

+--------+---------------+-----------+--------------+-----------+
|  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(第一个令牌的增量)
  • PositionIncrement(*)>=0(位置不得后退)
  • startOffset(“abc”)==startOffset(“a”)和endOffset(“abc”)==endOffset(“c”)
    • 实际上,处于相同(starttend)位置的令牌必须具有相同(starttend)偏移量

    希望这有助于揭示一些线索。

 类似资料:
  • 问题内容: 我已经将一个自定义distutils命令添加到setup.py脚本中: 有没有办法做到这一点,以便在运行时:: 第一次打电话 自动吗? 问题答案: 您可以覆盖:

  • 对于我们的应用程序,我们需要能够提供团体访问文件。每个用户可能拥有大量的组,因此使用“自定义令牌”解决方案是没有意义的(无论如何,这是非常尴尬的)。 我发现,Firebase的存储安全规则非常有限。主要问题是,我们将组定义保留在存储安全规则无法访问的Firestore中。 为了克服这个问题,我们决定在每个上传文件的元数据中包含一个“令牌”,组中的任何人都可以访问这个令牌。当他们下载一个文件时,他们

  • 问题内容: 我想知道如何使用此代码段: 我知道这是关于编译阶段的,但是我不明白这一点,所以简短的解释将是非常感谢。 问题答案: 将另一个指令添加到同一元素的指令: 类似答案: 这是一个小矮人:http ://plnkr.co/edit/ziU8d826WF6SwQllHHQq?p=preview 更清洁的解决方案-完全不使用: 矮人:http ://plnkr.co/edit/jY10enUVm3

  • 问题内容: 我们有一个简单的项目,我们从套接字读取数据,并希望用即将到来的数据填充表,但是我们找不到找到将行添加到尚未创建的对象的方法,只能在以下位置找到添加行的方法:表的创建时间。 是否可以向中动态添加行,或者有更好的替代对象来处理这种显示数据的方式? 编辑 :非常感谢您的回答。 他们三个看起来都很有前途,但是我只选择一个,我认为最好的就是纪尧姆的。 问题答案: 您应该创建一个自定义。A 实际上

  • 问题内容: 我有一个运行良好的Django应用程序。我正在添加REST服务。我正在寻找有关REST策略的其他信息。 以下是一些我正在绞尽脑汁的事例。 现在,我正在使用带有大量补丁的Django-REST API。 我正在考虑退一步,而只是在Django中编写返回JSON结果的视图函数。 我还可以看到在Apache中过滤REST请求并将它们路由到一个单独的非Django服务器实例。 请为每个答案指定

  • 我创建了一个JPanel,上面有我需要的所有JRadioButtons(称为PortSettings)。我还有一个按钮,叫做端口设置,当用户单击该按钮时,我需要JPanel上来显示单选按钮。我尝试将JPanel添加到actionlistener中,但没有效果。我的代码在下面。除了portsettings按钮之外,我已经从其他按钮中删除了所有其他ActionListener。如果这个问题让人困惑,我