【发布时间】:2014-05-26 09:59:43
【问题描述】:
我是 lucene.net 的新手。我想在客户端数据库上实现搜索功能。我有以下情况:
- 用户将根据当前选择的城市搜索客户。
- 如果用户想在另一个城市搜索客户,那么他必须更改城市并再次执行搜索。
-
要优化搜索结果,我们需要提供区域(多个)、Pincode 等过滤器。换句话说,我需要对以下 sql 查询等效的 lucene 查询:
SELECT * FROM CLIENTS WHERE CITY = N'City1' AND (Area like N'%area1%' OR Area like N'%area2%')SELECT * FROM CILENTS WHERE CITY IN ('MUMBAI', 'DELHI') AND CLIENTTYPE IN ('GOLD', 'SILVER')
下面是我实现的代码,以提供城市作为过滤器的搜索:
private static IEnumerable<ClientSearchIndexItemDto> _search(string searchQuery, string city, string searchField = "")
{
// validation
if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
return new List<ClientSearchIndexItemDto>();
// set up Lucene searcher
using (var searcher = new IndexSearcher(_directory, false))
{
var hits_limit = 1000;
var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
// search by single field
if (!string.IsNullOrEmpty(searchField))
{
var parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, searchField, analyzer);
var query = parseQuery(searchQuery, parser);
var hits = searcher.Search(query, hits_limit).ScoreDocs;
var results = _mapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
else // search by multiple fields (ordered by RELEVANCE)
{
var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, new[]
{
"ClientId",
"ClientName",
"ClientTypeNames",
"CountryName",
"StateName",
"DistrictName",
"City",
"Area",
"Street",
"Pincode",
"ContactNumber",
"DateModified"
}, analyzer);
var query = parseQuery(searchQuery, parser);
var f = new FieldCacheTermsFilter("City",new[] { city });
var hits = searcher.Search(query, f, hits_limit, Sort.RELEVANCE).ScoreDocs;
var results = _mapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
}
}
现在我必须提供更多关于 Area、Pincode 等的过滤器,其中 Area 是多个。我尝试了如下的 BooleanQuery:
var cityFilter = new TermQuery(new Term("City", city));
var areasFilter = new FieldCacheTermsFilter("Area",areas); -- where type of areas is string[]
BooleanQuery filterQuery = new BooleanQuery();
filterQuery.Add(cityFilter, Occur.MUST);
filterQuery.Add(areasFilter, Occur.MUST); -- here filterQuery.Add not have an overloaded method which accepts string[]
如果我们对单个区域执行相同的操作,那么它工作正常。
我已经尝试过如下所示的 ChainedFilter,它似乎不能满足要求。以下代码对城市和地区执行或操作。但要求是在给定城市提供的区域之间执行 OR 操作。
var f = new ChainedFilter(new Filter[] { cityFilter, areasFilter });
有人可以向我建议如何在 lucene.net 中实现这一点吗?您的帮助将不胜感激。
【问题讨论】:
标签: lucene.net