0

我有一个包含各个领域的 Lucene 文档;Name、BriefData、FullData、ParentIDs(逗号分隔的字符串)、ProductType、Experience。

我有一个带有文本框、父母下拉列表、产品类型下拉列表、体验下拉列表的搜索表单。

如果我从文本框中搜索,我会得到我应该得到的结果。如果我从任何下拉列表(或所有下拉列表)中搜索,我会得到我想要的结果。如果我使用下拉菜单和文本框,我会得到所有结果作为文本框或下拉菜单的搜索。我想要的是文本框和下拉菜单。

所以,我的搜索建立了这样的东西:

        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(名称或 BriefData 或 FullData 的“北”)的结果。

我尝试创建“+(Name:north BriefData:north FullData:north) +ParentIDs:62”和“Name:north BriefData:north FullData:north +ParentIDs:62”的 searchTerm。第一个不返回任何结果,第二个返回与仅搜索 +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 回答