【发布时间】:2020-04-07 07:52:29
【问题描述】:
标准分析器删除特殊字符,但不是全部(例如:'-')。我想只用字母数字字符索引我的字符串,但要引用原始文档。
示例:'doc-size type' 应该被索引为 'docsize' 和 'type' 并且都应该指向原始文档:'doc-size type'
【问题讨论】:
标签: filter lucene special-characters analyzer
标准分析器删除特殊字符,但不是全部(例如:'-')。我想只用字母数字字符索引我的字符串,但要引用原始文档。
示例:'doc-size type' 应该被索引为 'docsize' 和 'type' 并且都应该指向原始文档:'doc-size type'
【问题讨论】:
标签: filter lucene special-characters analyzer
这取决于您所说的“特殊字符”是什么意思,以及您可能还有什么其他要求。但以下内容可能会满足您的需求,或为您指明正确的方向。
以下示例均假设 Lucene 版本为 8.4.1。
从您给出的非常具体的示例开始,其中doc-size type 应该被索引为docsize 和type,这是一个自定义分析器:
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.WhitespaceTokenizer;
import org.apache.lucene.analysis.pattern.PatternReplaceFilter;
import java.util.regex.Pattern;
public class MyAnalyzer extends Analyzer {
@Override
protected TokenStreamComponents createComponents(String fieldName) {
final Tokenizer source = new WhitespaceTokenizer();
TokenStream tokenStream = source;
Pattern p = Pattern.compile("\\-");
boolean replaceAll = Boolean.TRUE;
tokenStream = new PatternReplaceFilter(tokenStream, p, "", replaceAll);
return new TokenStreamComponents(source, tokenStream);
}
}
这会在空白处拆分,然后使用PatternReplaceFilter 删除连字符。它的工作原理如下所示(我使用 「 和 」 作为分隔符来显示空格可能是输入/输出的一部分):
Input text:
「doc-size type」
Output tokens:
「docsize」
「type」
注意 - 这将删除 所有 连字符,它们是 标准键盘 连字符 - 但不会删除诸如 em-dashes、en-dashes 等内容。它将删除这些标准连字符,无论它们出现在文本中的什么位置(单词开头、单词结尾、单独等)。
您可以根据需要更改模式以覆盖更多标点符号 - 例如:
Pattern p = Pattern.compile("[$^-]");
执行以下操作:
Input text:
「doc-size type $foo^bar」
Output tokens:
「docsize」
「type」
「foobar」
您可以使用以下内容删除所有不是字符或数字的内容:
Pattern p = Pattern.compile("[^A-Za-z0-9]");
执行以下操作:
Input text:
「doc-size 123 %^&*{} type $foo^bar」
Output tokens:
「docsize」
「123」
「」
「type」
「foobar」
请注意,结果标签中有一个空字符串。
警告:以上内容是否适合您在很大程度上取决于您的具体、详细要求。例如,您可能需要执行额外的转换来处理大写/小写差异 - 即索引文本时通常需要考虑的常见事情。
StandardAnalyzer 实际上确实删除了单词中的连字符(有一些模糊的例外)。在您的问题中,您提到它不会删除它们。标准分析器使用标准标记器。标准分词器实现了 Unicode 文本分割算法中的分词规则,指定为 here。有一节讨论如何处理单词中的连字符。
所以,标准分析器会这样做:
Input text:
「doc-size type」
Output tokens:
「doc」
「size」
「type」
这应该适用于搜索 doc 和 doctype - 只是它是否能很好地满足您的需求的问题。
我知道这可能不是您想要的。但是,如果您可以避免构建自定义分析器,那么生活可能会简单得多。
【讨论】: