0

Lucene ベースの検索エンジン サイトに新しいフィールドを追加したいと考えていますが、クエリをインターセプトして、サーチャーに渡す前に変更できるようにしたいと考えています。

たとえば、各ドキュメントにはフィールドがあるuseridため、特定のユーザーが作成したドキュメントを ID でfoo bar userid:123検索できますが、ユーザー名で検索する機能を追加したいと考えています。

(ドキュメントではなくuser:RonaldMcDonald)クエリにフィールドを追加したいのですが、その用語をインターセプトして同等の用語に置き換えたいと考えています (自分のコードで "RonaldMcDonald" を "123" に変換する必要があります)。 .userid: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 と override をサブクラス化できます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 に答える