C# Lucene中的自定义过滤器

C# Lucene中的自定义过滤器,c#,lucene,C#,Lucene,我在analyzer中创建了一个自定义过滤器,用于按“/”字符拆分术语 我希望在搜索时可以找到包含字符串的文档,如“testDocument Test/mystring/2014”,例如“Test mystring”或“mystring 2014” 我实现了以下过滤器: public class MyDelimiterFilter : TokenFilter { private readonly ITermAttribute _termAtt; private readonly

我在analyzer中创建了一个自定义过滤器,用于按
“/”
字符拆分术语

我希望在搜索时可以找到包含字符串的文档,如
“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;
    }
}  
公共类MyDelimiterFilter:TokenFilter { 私有只读信息格式属性_termAtt; 私有只读IPositionIncrementAttribute\u positionAtt; 专用只读队列条款; public WordDelimiterFilter(流内令牌流) :基础(河道内) { _termAtt=AddAttribute(); _positionAtt=AddAttribute(); _terms=新队列(); } 公共覆盖bool IncrementToken() { 如果(_terms.Count!=0) { var buffer=_terms.Dequeue(); _termAtt.SETTERBUFFER(缓冲区,0,缓冲区长度); _位置att.PositionIncrement=1; 返回true; } 如果(!input.IncrementToken()) { 返回false; } if(_termAtt.Term.Contains(“/”) { var tempArray=_termAtt.Term.Split('/'); foreach(tempArray中的变量项) { _terms.Enqueue(item.ToCharArray()); } } 其他的 { _terms.Enqueue(_termAtt.Term.ToCharArray()); } 返回true; } } 我可以调试这段代码,逻辑路径似乎正确。如果我尝试搜索,我发现文档中有
“testDocument”
“Test/mystring/2014”
,但没有结果,例如
“mystring”

我想念什么

这部分:

    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;
不包含将
\u termAtt
设置为其正确值或增加位置的逻辑。从incrementToken返回true的次数将比通过这种方式返回true的次数要多。您能否在查询对象上提供
toString
方法中的文本

编辑:您返回的查询似乎是短语查询,而不是简单的术语查询。 尝试在最后一个
返回true之前添加此代码段语句

    var buffer = _terms.Dequeue();

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

作为调试度量,您还可以在
incrementToken
方法中打印一些内容,并查看对各种输入调用它的次数

查询是一个简单的
正文:“testDocument”
;有一个在线示例,或者您可以解释如何正确设置
\u termAtt
和位置吗?谢谢!照你说的去做是有效的!。。。在
IncrementToken
方法中,我通过更少的调用来加速代码执行相同的操作。逻辑似乎是一样的(更快的是),真正的区别在哪里?区别在于,当队列为空时,对增量令牌的调用将返回true,但
\u termAtt
将包含旧值而不是新生成的值,因此据我所知,您最终会得到重复的值