0

我想向基于 Lucene 的搜索引擎站点添加新字段,但是我希望能够在将查询传递给 Searcher 之前拦截并修改它们。

例如,每个文档都有该字段userid,因此您可以通过特定用户的 ID 搜索由特定用户创作的文档,例如,foo bar userid:123但是我想添加按用户名搜索的功能。

我想user:RonaldMcDonald向查询添加一个字段(而不是文档),但是我希望能够拦截该术语并将其替换为等效userid:123术语(我自己的代码将负责将“RonaldMcDonald”转换为“123”) .

这是我现在正在使用的简单代码:

Int32 get = (pageIndex + 1) * pageSize;

Query query;

try {

    query = _queryParser.Parse( queryText );

} catch(ParseException pex) {

    log.Add("Could not parse query.");
    throw new SearchException( "Could not parse query text.", pex );
}

log.Add("Parsed query.");

TopDocs result = _searcher.Search( query, get );

我查看了 Query 类,但看不到任何检索、删除或插入术语的方法。

4

1 回答 1

2

您可以继承 QueryParser 并覆盖NewTermQuery

QP qp = new QP("user", new SimpleAnalyzer());
var s = qp.Parse("user:RonaldMcDonald data:[aaa TO bbb]");

s将在哪里userid:123 data:[aaa TO bbb]

public class QP : QueryParser
{
    Dictionary<string, string> _dict = 
       new Dictionary<string, string>(new MyComparer()) {{"RonaldMcDonald","123"} };

    public QP(string field, Analyzer analyzer) : base(field, analyzer)
    {
    }

    protected override Query NewTermQuery(Term term)
    {
        if (term.Field() == "user")
        {
            //Do your username -> userid mapping
            return new TermQuery(new Term("userid", _dict[term.Text()]));
        }
        return base.NewTermQuery(term);
    }

    //Case insensitive comparer
    class MyComparer : IEqualityComparer<string>
    {
        public bool Equals(string x, string y)
        {
            return String.Compare(x, y, true, CultureInfo.InvariantCulture)==0;
        }

        public int GetHashCode(string obj)
        {
            return obj.ToLower(CultureInfo.InvariantCulture).GetHashCode();
        }
    }
}
于 2012-07-09T18:49:00.023 回答