0

さまざまなフィールドを持つ Lucene ドキュメントがあります。Name、BriefData、FullData、ParentIDs (カンマ区切りの文字列)、ProductType、エクスペリエンス。

テキストボックス、親のドロップダウン、製品タイプのドロップダウン、経験のドロップダウンを備えた検索フォームがあります。

テキストボックスから検索すると、必要な結果が得られます。ドロップダウンのいずれか (またはすべて) から検索すると、必要な結果が得られます。ドロップダウンとテキストボックスを使用すると、テキストボックスまたはドロップダウンの検索としてすべての結果が得られます。私が欲しいのは、テキストボックスとドロップダウンです。

だから、私の検索は次のようなものを構築します:

        if (string.IsNullOrWhiteSpace(searchTerm))
        {
            searchTerm = "";
            if (!string.IsNullOrWhiteSpace(Request.QueryString["textbox"]))
            {
                string tester = Request.QueryString["query"];
                searchTerm += tester;
            }
            if (!string.IsNullOrWhiteSpace(Request.QueryString["parent"]))
            {
                searchTerm += searchTerm.Length > 0 ? " " : "";
                searchTerm += "+ParentIDs:" + Request.QueryString["parent"];
            }
            if (!string.IsNullOrWhiteSpace(Request.QueryString["product"]))
            {
                ProductTypes pt = db.ProductTypes.Find(int.Parse(Request.QueryString["product"]));
                if (pt != null) {
                    searchTerm += searchTerm.Length > 0 ? " " : "";
                    searchTerm += "+ProductType:" + pt.TypeName;
                }
            }
            if (!string.IsNullOrWhiteSpace(Request.QueryString["experience"]))
            {
                searchTerm += searchTerm.Length > 0 ? " " : "";
                searchTerm += "+Experience:" + Request.QueryString["experience"];
            }
        }
        if (!Directory.Exists(Helper.LuceneSearch._luceneDir))
            Directory.CreateDirectory(Helper.LuceneSearch._luceneDir);

        _searchResults = string.IsNullOrEmpty(searchField)
                            ? Helper.LuceneSearch.Search(searchTerm).Distinct()
                            : Helper.LuceneSearch.Search(searchTerm, searchField).Distinct();

        return View(_searchResults.Distinct());

テキストボックスとドロップダウンの親だけを検索すると、「north +ParentIDs:62」という検索語が表示されます

私が望むのは、62 AND (Name OR BriefData OR FullData of "north") の親を持つ結果のみを返す検索です。

"+(Name:north BriefData:north FullData:north) +ParentIDs:62" と "Name:north BriefData:north FullData:north +ParentIDs:62" の searchTerm を作成してみました。1 つ目は結果を返さず、2 つ目は +ParentIDs:62 を検索した場合と同じ結果を返します。

この背後にあるロジックは非常に単純だと思います。しかし、コードで何を書く必要があるのか​​ わかりません。

助けてください。:)

4

1 に答える 1

2

JF Beaulac のおかげで、私が含めた Lucene.Net コード (Helper.LuceneSearch.Search(searchTerm).Distinct()) を見るきっかけを与えてくれました。

奇妙なことに、必要なマルチフィールド検索に MultiFieldQueryParser を使用してこれを行いました。次に、単一フィールドのクエリに TermQuery を使用しました。これらはすべて BooleanQuery に追加され、私の検索はその BooleanQuery に対して実行されました。

var hits_limit = 1000;
var analyzer = new StandardAnalyzer(Version.LUCENE_29);
BooleanQuery bq = new BooleanQuery();
if (string.IsNullOrWhiteSpace(searchTerm))
{
    searchTerm = "";
    if (!string.IsNullOrWhiteSpace(Request.QueryString["textbox"]))
    {
        string tester = Request.QueryString["textbox"];
        var parser = new MultiFieldQueryParser(Version.LUCENE_29, new[] { "Name", "BriefData", "FullData" }, analyzer);
        var query = Helper.LuceneSearch.parseQuery(tester.Replace("*", "").Replace("?", ""), parser);
        bq.Add(query, BooleanClause.Occur.MUST);
    }
    if (!string.IsNullOrWhiteSpace(Request.QueryString["parent"]))
    {
        bq.Add(new TermQuery(new Term("ParentIDs", Request.QueryString["parent"])), BooleanClause.Occur.MUST);
    }
    if (!string.IsNullOrWhiteSpace(Request.QueryString["product"]))
    {
        ProductTypes pt = db.ProductTypes.Find(int.Parse(Request.QueryString["product"]));
        if (pt != null) {
            bq.Add(new TermQuery(new Term("ProductType", pt.TypeName)), BooleanClause.Occur.MUST);
        }
    }
    if (!string.IsNullOrWhiteSpace(Request.QueryString["experience"]))
    {
        bq.Add(new TermQuery(new Term("Experience", Request.QueryString["experience"])), BooleanClause.Occur.MUST);
    }
}
if (!System.IO.Directory.Exists(Helper.LuceneSearch._luceneDir))
    System.IO.Directory.CreateDirectory(Helper.LuceneSearch._luceneDir);

var searcher = new IndexSearcher(Helper.LuceneSearch._directory, false);
var hits = searcher.Search(bq, null, hits_limit, Sort.RELEVANCE).ScoreDocs;
var results = Helper.LuceneSearch._mapLuceneToDataList(hits, searcher).Distinct();
analyzer.Close();
searcher.Close();
searcher.Dispose(); 

return View(results);

製品と経験のフィールドを機能させるには、インデックスに追加するときに「Field.Index.NOT_ANALYZED」に設定する必要があったことに注意してください。これは、ドキュメントごとに単一の値しか持たないためだと思います。他の検索フィールドは「Field.Index.ANALYZED」です。

于 2012-08-25T07:24:56.270 に答える