如何在Lucene.net中拒绝数值?

时间:2013-04-22 18:33:30

标签: lucene.net

我想知道在Lucene.net中编制索引或搜索时是否可以拒绝数字短语或数值。

例如(这是一行),

Hi all my no is 4756396

现在,当我索引或搜索时,它应该拒绝要索引或搜索的数值4756396。我尝试使用1,2,3,4,5,6等制作自定义停用词列表,但我想只会出现一个数字时才会忽略。

1 个答案:

答案 0 :(得分:1)

您可以复制StandardAnalyzer并自定义语法(简单的JFlex内容)以拒绝数字令牌。如果你这样做,你需要将分析器移回给Java,因为JFlex会生成java代码,你可以尝试使用C#Flex。

您还可以编写一个TokenFilter逐个扫描令牌,如果它们是数字则拒绝它们。如果您只想过滤整数并且仍然保留例如用连字符分隔的数字,则过滤器可以简单地尝试double.TryParse(),如果失败则接受令牌。更强大和可定制的解决方案仍然使用词法解析器。

编辑:

下面简要介绍一下我的意思,用一个主要的方法来展示如何使用它。在这里我使用TryParse()来过滤掉令牌,如果它是用于更复杂的生产系统,我会使用词法解析器系统。 (看看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);
}