Более быстрый способ получить отличные значения от Lucene Query - PullRequest
4 голосов
/ 06 марта 2009

В настоящее время мне нравится:

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

Как видите, я сначала собираю ВСЕ поля (несколько тысяч), а затем различаю их, возможно, пропускаю некоторые и вынимаю некоторые.

Я чувствую, что должен быть лучший способ сделать это.

Ответы [ 4 ]

3 голосов
/ 06 марта 2009

Связывая этот вопрос с более ранним вашим вопросом («Слишком много предложений»), я думаю, что вам определенно следует взглянуть на перечисление терминов из программы чтения индекса. Кэшируйте результаты (я использовал отсортированный словарь с ключом по имени поля, со списком терминов в качестве данных, максимум до 100 терминов на поле), пока читатель индекса не станет недействительным, и вы уйдете.

Или, может быть, я должен сказать, что когда я столкнулся с проблемой, подобной вашей, именно это я и сделал.

Надеюсь, это поможет,

1 голос
/ 24 июля 2013
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;
    }
1 голос
/ 20 апреля 2012

Я предлагаю вам найти логику, чтобы пропустить этот тип итерации, но если в вашем контексте нет решения, то вы можете получить выигрыш в производительности с помощью следующего кода
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);

Производительность приведенного выше кода намного выше, чем у предоставленного вами кода, поскольку он пропускает чтение ненужных полей документа и экономит время.

0 голосов
/ 06 марта 2009

Я не уверен, что, если честно, Lucene не предоставляет «отличную» функциональность. Я полагаю, что с помощью SOLR вы можете использовать поиск фасетов для достижения этой цели, но если вы хотите этого в Lucene, вам придется самостоятельно написать какую-то функцию фасетов. Поэтому до тех пор, пока у вас не возникнут какие-либо проблемы с производительностью, все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...