質問
現在、私はこうしています:
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();
ご覧のとおり、最初にすべてのフィールド(数千)を収集し、次にそれらを区別します。一部をスキップして一部を削除します。
これを行うにはもっと良い方法があるべきだと思う。
解決
Luceneが「個別の」機能を提供していないため、正直なところ、それがあるかどうかはわかりません。 SOLRでは、ファセット検索を使用してこれを実現できると考えていますが、Luceneでこれを行う場合は、何らかのファセット機能を自分で作成する必要があります。したがって、パフォーマンスの問題が発生しない限り、この方法で問題ないはずです。
他のヒント
この質問をあなたの以前の質問(「:句が多すぎます」)に結びつけると、インデックスリーダーからの用語列挙を間違いなく見るべきだと思います。結果をキャッシュします(フィールド名にキーを付けたソート済み辞書をデータとして用語のリストとともに使用し、フィールドごとに最大100語まで)インデックスリーダーが無効になり、すぐに消えます。
または、おそらくあなたと同じような問題に直面したとき、それが私がしたことだと言うべきでしょう。
これがお役に立てば幸いです
この種の反復をスキップするロジックを見つけることをお勧めしますが、コンテキストに解決策がない場合は、次のコードでパフォーマンスを向上させることができます
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);
上記のコードのパフォーマンスは、不要なドキュメントフィールドの読み取りをスキップし、時間を節約するため、指定したコードよりもはるかに優れています。
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;
}