我想知道在 Lucene.net 中进行索引或搜索时是否可以拒绝数字短语或数值。
例如(这是一行),
Hi all my no is 4756396
现在,当我索引或搜索时,它应该拒绝要索引或搜索的数值 4756396。我尝试使用 1、2、3、4、5、6 等制作自定义停用词列表,但我想它只会在出现单个数字时忽略。
我想知道在 Lucene.net 中进行索引或搜索时是否可以拒绝数字短语或数值。
例如(这是一行),
Hi all my no is 4756396
现在,当我索引或搜索时,它应该拒绝要索引或搜索的数值 4756396。我尝试使用 1、2、3、4、5、6 等制作自定义停用词列表,但我想它只会在出现单个数字时忽略。
您可以复制StandardAnalyzer
并自定义语法(简单的 JFlex 内容)以拒绝数字标记。如果这样做,您需要将分析器移植回 Java,因为 JFlex 将生成 Java 代码,您可以尝试使用 C# Flex。
您还可以编写一个TokenFilter
逐个扫描令牌并拒绝它们(如果它们是数字)。如果您只想过滤整数并且仍然保留例如由连字符分隔的数字,则过滤器可以简单地尝试 adouble.TryParse()
并且如果失败则接受令牌。更健壮和可定制的解决方案仍将使用词法解析器。
这是我的意思的一个快速示例,并带有一个显示如何使用它的主要方法。在此我使用 aTryParse()
来过滤掉标记,如果是用于更复杂的生产系统,我会使用词法解析器系统。(看看C# Flex)
public class NumericFilter : TokenFilter
{
private ITermAttribute termAtt ;
public NumericFilter(TokenStream tokStream)
: base(tokStream)
{
termAtt = AddAttribute<ITermAttribute>();
}
public override bool IncrementToken()
{
while (base.input.IncrementToken())
{
string term = termAtt.Term;
double res ;
if(double.TryParse(term, out res))
{
// skip this token
continue;
}
// accept this token
return true;
}
// no more token in the stream
return false;
}
}
static void Main(string[] args)
{
RAMDirectory dir = new RAMDirectory();
IndexWriter iw = new IndexWriter(dir, new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
Document d = new Document();
Field f = new Field("text", "", Field.Store.YES, Field.Index.ANALYZED);
d.Add(f);
// use our Filter here
f.SetTokenStream(new NumericFilter(new LowerCaseFilter(new WhitespaceTokenizer(new StringReader("I have 300 dollars")))));
iw.AddDocument(d);
iw.Commit();
IndexReader reader = iw.GetReader();
// print all terms in the text field
TermEnum terms = reader.Terms(new Term("text", ""));
do
{
Console.WriteLine(terms.Term.Text);
}
while (terms.Next());
reader.Dispose();
iw.Dispose();
Console.ReadLine();
Environment.Exit(42);
}