目前我喜欢这个:
IndexSearcher searcher = new IndexSearcher(lucenePath);
Hits hits = searcher.Search(query);
Document doc;
List<string> companyNames = new List<string>();
for (int i = 0; i < hits.Length(); i++)
{
doc = hits.Doc(i);
companyNames.Add(doc.Get("companyName"));
}
searcher.Close();
companyNames = companyNames.Distinct<string>().Skip(offSet ?? 0).ToList();
return companyNames.Take(count??companyNames.Count()).ToList();
正如你所看到的,我首先收集所有字段(数千个),然后区分它们,可能会跳过一些并取出一些。
我觉得应该有更好的方法来做到这一点。
答案 0 :(得分:3)
将此问题与您之前的问题联系起来(重新:“太多条款”),我认为您绝对应该从索引阅读器中查看术语枚举。缓存结果(我使用键入字段名称的排序字典,以及作为数据的术语列表,每个字段最多100个术语),直到索引阅读器变为无效并离开。
或者我应该说,当遇到类似的问题时,我就是这么做的。
希望这有帮助,
答案 1 :(得分:1)
我建议你找一个跳过这种迭代的逻辑但是如果你的上下文中没有解决方案那么你可以通过以下代码获得性能提升 1)在索引时,最好在第一个字段
中放置要迭代的字段Document doc = new Document();
Field companyField = new Field(...);
doc.Add(companyField);
...
2)然后你需要像这样定义一个FieldSelector
class CompanyNameFieldSelector : FieldSelector
{
public FieldSelectorResult Accept(string fieldName)
{
return (fieldName == "companyName" ? FieldSelectorResult.LOAD_AND_BREAK : FieldSelectorResult.NO_LOAD);
}
}
3)然后当你想迭代并选择这个字段时,你应该做这样的事情
FieldSelector companySelector = new CompanyNameFieldSelector();
// when you iterate through your index
doc = hits.Doc(i);
doc.Get("companyName", companySelector);
上述代码的性能远远优于您提供的代码,因为它会跳过阅读不必要的文档字段,并节省时间。
答案 2 :(得分:1)
public List<string> GetDistinctTermList(string fieldName)
{
List<string> list = new List<string>();
using (IndexReader reader = idxWriter.GetReader())
{
TermEnum te = reader.Terms(new Term(fieldName));
if (te != null && te.Term != null && te.Term.Field == fieldName)
{
list.Add(te.Term.Text);
while (te.Next())
{
if (te.Term.Field != fieldName)
break;
list.Add(te.Term.Text);
}
}
}
return list;
}
答案 3 :(得分:0)
老实说,我不确定是不是因为Lucene没有提供“独特”的功能。我相信使用SOLR可以使用方面搜索实现这一点,但如果你想在Lucene中使用它,你必须自己编写某种方面的功能。因此,只要您不遇到任何性能问题,就应该这样。