【问题标题】:Custom filter in LuceneLucene 中的自定义过滤器
【发布时间】:2014-06-23 12:37:26
【问题描述】:

我在分析器中创建了一个自定义过滤器,以按 "/" 字符分割术语。

我希望可以通过搜索找到包含"testDocument Test/mystring/2014" 之类的字符串的文档,例如"test mystring""mystring 2014"

我实现了以下过滤器:

public class MyDelimiterFilter : TokenFilter
{

    private readonly ITermAttribute _termAtt;
    private readonly IPositionIncrementAttribute _positionAtt;
    private readonly Queue<char[]> _terms;

    public WordDelimiterFilter(TokenStream inStream)
        : base(inStream)
    {
        _termAtt = AddAttribute<ITermAttribute>();
        _positionAtt = AddAttribute<IPositionIncrementAttribute>();
        _terms = new Queue<char[]>();
    }

    public override bool IncrementToken()
    {
        if (_terms.Count != 0)
        {
            var buffer = _terms.Dequeue();

            _termAtt.SetTermBuffer(buffer,0,buffer.Length);
            _positionAtt.PositionIncrement = 1;
            return true;
        }

        if (!input.IncrementToken())
        {
            return false;
        }

        if (_termAtt.Term.Contains("/"))
        {
            var tempArray = _termAtt.Term.Split('/');
            foreach (var item in tempArray)
            {
                _terms.Enqueue(item.ToCharArray());
            }
        }
        else
        {
            _terms.Enqueue(_termAtt.Term.ToCharArray());
        }

        return true;
    }
}  

我可以调试此代码并且逻辑路径似乎正确。如果我尝试搜索,我会找到带有 "testDocument""Test/mystring/2014" 但结果为零的文档,例如 "mystring"

我想念什么?

【问题讨论】:

    标签: c# lucene


    【解决方案1】:

    这部分:

        if (_termAtt.Term.Contains("/"))
        {
            var tempArray = _termAtt.Term.Split('/');
            foreach (var item in tempArray)
            {
                _terms.Enqueue(item.ToCharArray());
            }
        }
        else
        {
            _terms.Enqueue(_termAtt.Term.ToCharArray());
        }
    
        return true;
    

    不包含将_termAtt 设置为正确值或增加位置的逻辑。您将比这种方式更多地从 incrementToken 返回 true。您能否在查询对象上提供 toString 方法中的文本?

    编辑:您返回的查询似乎是短语查询而不是简单的术语查询。 尝试在最后的 return true; 语句之前添加此代码 sn-p

        var buffer = _terms.Dequeue();
    
        _termAtt.SetTermBuffer(buffer,0,buffer.Length);
        _positionAtt.PositionIncrement = 1;
    

    作为一种调试措施,您还可以在 incrementToken 方法中打印一些内容,并查看它为各种输入调用了多少次

    【讨论】:

    • 查询是一个简单的Body:"testDocument";有在线示例或者你能解释一下如何正确设置_termAtt和位置吗?
    • 谢谢!按照你的描述做是有效的!......我加快了代码在IncrementToken方法上的调用次数更少。逻辑似乎相同(更快是的)真正的区别在哪里?
    • 不同之处在于,当队列为空时,对增量令牌的调用将返回 true ,但 _termAtt 将包含旧值而不是新生成的值,因此您最终会得到重复值据我所知
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多