Lucene-如何修改查询对象';什么条件?

Lucene-如何修改查询对象';什么条件?,lucene,lucene.net,Lucene,Lucene.net,我想在我基于Lucene的搜索引擎站点上添加新字段,但是我希望能够在将查询传递给搜索者之前拦截查询并修改它们 例如,每个文档都有userid字段,因此您可以根据特定用户的ID搜索其编写的文档,例如foo-bar-userid:123,但是我想添加按用户名搜索的功能 我想在查询中添加一个字段user:RonaldMcDonald(而不是到文档),但是我希望能够截取该术语,并将其替换为等效的userid:123术语(我自己的代码将负责将“RonaldMcDonald”转换为“123”) 下面是我现在

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

例如,每个文档都有
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类,但是我看不到任何检索、删除或插入术语的方法。

您可以将QueryParser子类化并覆盖
NewTermQuery

QP qp = new QP("user", new SimpleAnalyzer());
var s = qp.Parse("user:RonaldMcDonald data:[aaa TO bbb]");
其中
s
userid:123数据:[aaa到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();
        }
    }
}
公共类QP:QueryParser
{
字典_dict=
新字典(新MyComparer()){{“麦当劳”,“123”};
公共QP(字符串字段,分析器):基本(字段,分析器)
{
}
受保护的覆盖查询NewTermQuery(术语)
{
if(term.Field()=“用户”)
{
//进行用户名->用户ID映射
返回新的TermQuery(新的Term(“userid”),_dict[Term.Text());
}
返回base.NewTermQuery(术语);
}
//不区分大小写的比较器
班级比较:IEqualityComparer
{
公共布尔等于(字符串x、字符串y)
{
返回String.Compare(x,y,true,CultureInfo.InvariantCulture)==0;
}
public int GetHashCode(字符串obj)
{
返回obj.ToLower(CultureInfo.InvariantCulture.GetHashCode();
}
}
}

为什么不为用户名编制索引?我无法为用户名字符串编制索引,因为它们经常更改(用户数据库有大约200000个条目,每天大约发生10次用户名更改),但索引需要保持不变(除了添加新文档)。谢谢。我希望在不合格的搜索词上使用你的技巧。例如:将“RonaldMcDonald”(无字段前缀)直接转换为“userid:123”。它不起作用,因为QueryParser预先应用了默认字段,所以
term.field
永远不会为空。如果我将默认字段设置为空,但我使用的是
KeywordAnalyzer
:使用默认字段空,QueryParser将短语“bigmac”解析为文本为“bigmac”的
TermQuery
。你知道怎么做吗?我正在使用Lucene.NET2.9.4g。