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