我正在玩Lucene,并注意到使用连字符(例如“半决赛”)将导致两个单词(索引中的“半”和“最终”。如果匹配的话,这应该如何匹配用户用一个词来搜索“半决赛”吗?
编辑:我实际上只是在玩StandardTokenizer类,也许这就是为什么?我错过了过滤器吗?
谢谢!
(编辑) 我的代码如下所示:
StandardAnalyzer sa = new StandardAnalyzer();
TokenStream ts = sa.TokenStream("field", new StringReader("semi-final"));
while (ts.IncrementToken())
{
string t = ts.ToString();
Console.WriteLine("Token: " + t);
}
答案 0 :(得分:2)
我建议你使用Solr的WordDelimiterFilter(你可以在你的Lucene应用程序中使用它作为添加到你的分析器的TokenFilter,只需从Solr获取此过滤器的java文件并将其添加到你的应用程序中)。 / p>
此过滤器旨在处理如下情况: http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.WordDelimiterFilterFactory
答案 1 :(得分:1)
这是lucene中的tokenizer的解释
- Splits words at punctuation
characters, removing punctuation.
However, a dot that's not followed by
whitespace is considered part of a
token.
- Splits words at hyphens, unless
there's a number in the token, in
which case the whole token is
interpreted as a product number and
is not split.
- Recognizes email addresses and internet hostnames as one token.
这解释了为什么它会分裂你的话。
这可能是最难纠正的,人为错误。如果一个人在半决赛中输入,这在理论上与搜索半决赛不同。所以如果你有很多单词可以用不同的方式输入ex:
你坚持完成任务 st和saint以及连字符或非连字符。你的代币将是巨大的,每个单词都需要进行比较,看看它们是否匹配。的St-恒
圣常数
圣恒
我仍然在寻找是否有一种很好的方法来接近这个,否则,如果你没有很多想要使用的单词,那么就可以存储和测试所有的可能性,或者有一个循环分裂从第一个字母开始的单词并在每个字母中移动,将字符串分成两半以形成两个单词,测试整个过程以查看它是否匹配。但再次说你只有2个字。如果您要验证多于两个单词,那么您就会遇到在多个部分中拆分单词的问题
例如
saint-jean-sur-richelieu
如果我拿出别的东西,我会告诉你。
答案 2 :(得分:1)
如果您正在寻找WordDelimiterFilter的端口,那么我建议谷歌WordDelimiter.cs,我在这里找到了这样一个端口:
http://osdir.com/ml/attachments/txt9jqypXvbSE.txt
然后我创建了一个非常基本的WordDelimiterAnalyzer:
public class WordDelimiterAnalyzer: Analyzer
{
#region Overrides of Analyzer
public override TokenStream TokenStream(string fieldName, TextReader reader)
{
TokenStream result = new WhitespaceTokenizer(reader);
result = new StandardFilter(result);
result = new LowerCaseFilter(result);
result = new StopFilter(true, result, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
result = new WordDelimiterFilter(result, 1, 1, 1, 1, 0);
return result;
}
#endregion
}
我说这是基本的:)
如果有人有实施,我会很想看到它!
答案 3 :(得分:0)
您可以编写自己的标记生成器,它将为带有连字符的单词生成所有可能的标记组合:
您需要设置正确的令牌偏移量来告诉lucene半场半决赛实际上是从文档中的同一位置开始的。
答案 4 :(得分:0)
规则(对于经典分析器)来自于jflex:
// floating point, serial, model numbers, ip addresses, etc.
// every other segment must have at least one digit
NUM = ({ALPHANUM} {P} {HAS_DIGIT}
| {HAS_DIGIT} {P} {ALPHANUM}
| {ALPHANUM} ({P} {HAS_DIGIT} {P} {ALPHANUM})+
| {HAS_DIGIT} ({P} {ALPHANUM} {P} {HAS_DIGIT})+
| {ALPHANUM} {P} {HAS_DIGIT} ({P} {ALPHANUM} {P} {HAS_DIGIT})+
| {HAS_DIGIT} {P} {ALPHANUM} ({P} {HAS_DIGIT} {P} {ALPHANUM})+)
// punctuation
P = ("_"|"-"|"/"|"."|",")