C# 从Lucene查询中获取不同值的更快方法

C# 从Lucene查询中获取不同值的更快方法,c#,lucene,C#,Lucene,目前我喜欢这样: 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); co

目前我喜欢这样:

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();
IndexSearcher searcher=newindexsearcher(lucenePath);
Hits=searcher.Search(查询);
文件文件;
列表公司名称=新列表();
对于(int i=0;i
如您所见,我首先收集所有字段(数千个),然后将它们区分开来,可能会跳过一些字段,然后取出一些字段


我觉得应该有更好的方法来做到这一点。

老实说,我不确定是否有,因为Lucene没有提供“独特”的功能。我相信有了SOLR,您可以使用方面搜索来实现这一点,但是如果您想在Lucene中实现这一点,您必须自己编写一些方面功能。因此,只要您没有遇到任何性能问题,您就应该这样做。

将这个问题与您前面的问题(关于:“太多子句”)联系起来,我认为您肯定应该从索引读取器中查看术语枚举。缓存结果(我使用了一个字段名上键入的排序字典,以术语列表作为数据,每个字段最多100个术语),直到索引读取器变得无效并离开

或者我应该说,当我面临与你类似的问题时,我就是这么做的


希望这会有所帮助,

我建议您找到一种逻辑来跳过这种迭代,但是如果您的上下文中没有解决方案,那么您可以通过以下代码获得性能提升
1) 在索引时,最好将要迭代的字段放在第一个字段中

Document doc = new Document();
Field companyField = new Field(...);
doc.Add(companyField);
...
2) 然后你需要像这样定义一个字段选择器

class CompanyNameFieldSelector : FieldSelector
{
    public FieldSelectorResult Accept(string fieldName)
    {
        return (fieldName == "companyName" ? FieldSelectorResult.LOAD_AND_BREAK : FieldSelectorResult.NO_LOAD);
    }
}
FieldSelector companySelector = new CompanyNameFieldSelector();
// when you iterate through your index
doc = hits.Doc(i);
doc.Get("companyName", companySelector);
3) 然后,当您想要迭代并选择这个字段时,您应该执行如下操作

class CompanyNameFieldSelector : FieldSelector
{
    public FieldSelectorResult Accept(string fieldName)
    {
        return (fieldName == "companyName" ? FieldSelectorResult.LOAD_AND_BREAK : FieldSelectorResult.NO_LOAD);
    }
}
FieldSelector companySelector = new CompanyNameFieldSelector();
// when you iterate through your index
doc = hits.Doc(i);
doc.Get("companyName", companySelector);
上述代码的性能比您提供的代码要好得多,因为它跳过了读取不必要的文档字段,节省了时间。

public List GetDistinctTermList(string fieldName)
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;
    }
{ 列表=新列表(); 使用(IndexReader reader=idxWriter.GetReader()) { TermEnum te=reader.Terms(新术语(字段名)); if(te!=null&&te.Term!=null&&te.Term.Field==fieldName) { 列表.添加(术语.文本); while(te.Next()) { if(te.Term.Field!=字段名) 打破 列表.添加(术语.文本); } } } 退货清单; }
您能否详细说明“术语枚举”的含义?你的意思是枚举我的所有文档并获取这些字段,这样我就可以使用C#的StartsWith()?看看IndexReader类的Terms成员函数。顺便说一句,我通过查看Luke的源代码发现了很多关于这类事情的信息。非常有趣!实际上我不是卢克的超级粉丝。我不知道为什么,但每个查询都需要很长时间才能解析。比我自己的查询慢多了。