Frage

Zur Zeit ich tun, wie folgt:

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();

Wie Sie sehen können, habe ich alle Felder zuerst sammeln (mehrere Tausend) und dann verschieden sie, möglicherweise einige überspringen und etwas aus nehmen.

Ich fühle mich wie sollte es ein besserer Weg, dies zu tun.

War es hilfreich?

Lösung

Ich bin mir nicht sicher, es ist, ehrlich gesagt, wie Lucene bietet keine ‚eindeutige‘ -Funktionalität. Ich glaube, mit SOLR können Sie eine Facette Suche verwenden, um dies zu erreichen, aber wenn Sie dies wollen in Lucene, würden Sie sich selbst eine Art von Facette Funktionalität zu schreiben. Also, solange Sie nicht in irgendwelche Performance-Probleme laufen, sollten Sie in Ordnung sein auf diese Weise.

Andere Tipps

bindet diese Frage zu einer früheren Frage von Ihnen (re: „Zu vielen Klauseln“), ich glaube, Sie sollten auf jeden Fall bei Begriff Aufzählung aus dem Index Leser suchen. Cache, um die Ergebnisse (Ich habe ein sortiertes Wörterbuch verkeilt auf den Feldnamen, mit einer Liste von Begriffen, wie die Daten, zu einem Maximum von 100 Begriffe pro Feld), bis der Index Leser wird ungültig, und gehen Sie weg.

Oder vielleicht sollte ich sagen, dass, wenn sie mit einem ähnlichen Problem zu Ihnen gegenüber, das ist, was ich getan habe.

Hope, das hilft,

Ich schlage vor, Sie eine Logik zu finden, diese Art von Iteration zu überspringen, aber wenn es keine Lösung in Ihrem Kontext ist, dann können Sie einen Performance-Gewinn mit dem folgenden Code
erhalten 1) am Index Zeit ist es am besten, um das Feld zu setzen, die Sie durchlaufen wollen, in ersten Bereich

Document doc = new Document();
Field companyField = new Field(...);
doc.Add(companyField);
...

2), dann benötigen Sie einen FieldSelector so definieren

class CompanyNameFieldSelector : FieldSelector
{
    public FieldSelectorResult Accept(string fieldName)
    {
        return (fieldName == "companyName" ? FieldSelectorResult.LOAD_AND_BREAK : FieldSelectorResult.NO_LOAD);
    }
}

3) Dann, wenn Sie möchten, um dieses Feld zu durchlaufen und holen Sie so etwas tun sollen

FieldSelector companySelector = new CompanyNameFieldSelector();
// when you iterate through your index
doc = hits.Doc(i);
doc.Get("companyName", companySelector);

Die Leistung der oben genannten Code ist viel besser als der Code, den Sie vorgesehen Ursache überspringen unnötige Dokumentenfelder zu lesen, und Zeit sparen.

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;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top