[英]lucene.net search multiple fields with one value AND other field with another value
我有一个各种领域的Lucene doc; 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(名称OR BriefData或FullData为“north”)的结果。
我尝试创建一个“+(名称:北方简要数据:北方FullData:北方)+父级ID:62”和“名称:北方简要数据:北方FullData:北方+父级ID:62”的searchTerm。 第一个返回没有结果,第二个返回相同的只是搜索+ ParentIDs:62。
我认为这背后的逻辑非常简单。 但是,我不知道我需要在代码中编写什么。
请帮忙。 :)
感谢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”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.