Lucene的。索引文本中每个单词的几个标记

时间:2015-12-27 10:17:27

标签: java lucene query-analyzer

我正在使用lucene 3.5和SpanishAnalyzer(它本身使用SpanishStemmerStandardTokenizer)。
当SpanishAnalyzer使用单词(例如)“claramente”和“claro”索引文档时,它们都将被索引为“clar”。
这种行为在我查询之前就已被理解并且对我的需求很有用,我在使用Analyzer tokenStream + incrementToken()来获取搜索词的标记并针对索引文档进行搜索。我没有使用QueryParser,而是在代码中构建lucene查询对象 但是我想要能够搜索确切的单词(在这个示例claro中),而不会失去SpanishAnalyzer的形态能力。
我可以跳过上面的步骤(tokenStream)并直接搜索“claro”,但它不会被找到,因为它被索引为“clar”。
此外,我不想使用2个不同的分析器对字段进行两次索引,因为我需要能够使用包含一个精确单词和一个常规术语(形态学)的PhraseQuerySpanNearQuery
所以......我已经到了这一点......我想要修改Tokenizer或Stemmer或Filter(?)所以在索引时间它会为每个单词索引2个标记,包括一个和原始单词,在本例中为“claro” “和”clar“以后查询时我可以选择使用确切的单词还是使用词干 我需要帮助了解我能做到的方式(以及在哪里),我想编辑应该在Stemmer中的某个地方完成。

顺便说一下,我使用希伯来语分析器做同样的事情,当使用incrementToken()时,我会为文本中的每个单词返回几个标记(但我没有源代码)

2 个答案:

答案 0 :(得分:3)

您需要一个每个位置有多个令牌的索引,因为您希望搜索带有词干标记和非词干(=原始)标记混合的短语。 我会回答5.3版,但3.5并没有太大差异。

查看solr中ALTER TABLE Syntax的源代码。 您将在每个令牌上看到两个步骤:

  1. 使用原始令牌存储当前ReversedWildcardFilter。因此,state - 方法的第一次调用将获得带柄令牌,第二次调用将获得原始令牌(具有相同位置)
  2. 选择“markerChar”作为词干标记的前缀。因此,在搜索时,您可以决定是否要使用词干或原始令牌进行搜索。
  3. 对于您的SpanishAnalyzer,这意味着例如以下内容:

    SpanishAnalyzer的核心是SpanishLightStemFilter。 SpanishLightStemFilter仅使用incrementToken()来阻止令牌。因此,对于index-time,在SpanishAnalyzer中插入一个KeywordRepeatFilter,并用前缀标记带梗的标记。

答案 1 :(得分:0)

有一个令牌过滤器可以非常轻松地启用此功能,KeywordRepeatFilter<?php $oldpass = 'mypassword1'; $newpass = 'mypassword2'; preg_match('/^([^\d]+)([\d]*?)$/', $oldpass, $match); $string = $match[1]; $number = $match[2] + 1; $string .= $number; $valid = $newpass === $string ? false : true; var_dump($valid); ?> 尊重KeywordAttribute)。只需在Stemmer之前将其添加到您的分析链中。对于SpanishAnalyzer,SpanishLightStemFilter方法如下所示:

createComponents

这不允许您明确搜索仅限于未受干扰的术语,但它会将原始术语保留在与词干相同的位置,从而可以轻松地将它们考虑到词组查询中。如果你确实只需要明确地搜索词干或只有未被干扰的术语,那么在单独的字段中编制索引真的是更好的方法。