Как я могу заказать список в LuceneSearch по количеству просмотров - PullRequest
1 голос
/ 04 августа 2009

Я использую Lucene Search, чтобы получить статьи, соответствующие тексту поиска. Есть ли способ получить их в порядке возрастания количества попаданий в статье.

Пример: если мой текст для поиска stack и в первой статье есть два вхождения слова stack, а во второй статье три вхождения stack, то второе должно идти первым, а первое надо идти вторым.

Есть идеи, как мне это сделать?

Ниже приведен код, который я использую

List<LuceneSearchResult> searchResult = new List<LuceneSearchResult>();
LuceneSearchResult result;
IndexReader reader = IndexReader.Open(INDEX_DIR);
Searcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();

QueryParser parser = new QueryParser("Text", analyzer);
//Text and Type are column name

Query q = parser.Parse(string.Format("Text:{0} AND Type:{1}", finalText, type));
Hits hs = searcher.Search(q);
ArrayList idList = new ArrayList();
for (int i = 0; i < hs.Length(); i++)
{

    Document doc = hs.Doc(i);
    result = new LuceneSearchResult();
    result.ID = doc.Get("ID");
    result.Type = doc.Get("Type");


    if (!idList.Contains(result.ID))
    {
        searchResult.Add(result);
        idList.Add(result.ID);
    }

}
return searchResult.ToArray();

Ответы [ 5 ]

2 голосов
/ 06 августа 2009

Lucene ранжирует документы по счету. Есть несколько компонентов для оценки документа по заданному запросу. Одним из них является частота термина в поле запроса. Однако для поиска по одному термину расчет довольно прост. Он пропорционален квадратному корню из числа вхождений члена в поле , нормализовано по длине поля. Это может быть там, где у вас проблемы.

Если вы выполняете поиск по слову «стек», и у документа А 1 случай, а у документа 2 2 случая, документ А все равно может иметь более высокий ранг в результатах, если длина поля значительно больше, чем у документа В.

Хорошей новостью является то, что вы можете отключить нормализацию поля. Плохая новость заключается в том, что вам нужно сделать это до того, как индексировать, , если не превысит класс сходства, чтобы всегда учитывать его, но я бы не рекомендовал делать это таким образом. Чтобы отключить нормы во время индексирования, в коде индексации вызовите Field.setOmitNorms (true) для объекта Field, который вы добавляете в IndexWriter. В вашем случае это будет для поля «текст».

1 голос
/ 04 августа 2009

Lucene должен делать это автоматически, но это зависит от того, как вы сформулируете свой запрос. По умолчанию, если вы делаете запрос с более чем одним словом, то это ORd вместе. Например, скажем, ваш запрос был что-то вроде этого (поиск в поле содержимого):

contents:apples oranges

Это вернет любые страницы с термином яблоки ИЛИ апельсины. Если страница содержит слово «яблоки» 50 раз, но нет ссылки на оранжевый, эта страница все равно будет иметь более высокий рейтинг, чем страница, на которой только один раз содержалось слово «яблоки» и «апельсины» один раз.

Что вы, вероятно, хотите сделать, и ваш запрос, как этот:

contents:apples AND oranges

Примечание: заглавные буквы И

Это вернет только те страницы, на которых есть слово «яблоки» и «апельсины», что, вероятно, ближе к тому, что вы хотите.

Прочитайте Lucene - синтаксический анализатор запросов для получения дополнительной информации о том, как формировать запросы

0 голосов
/ 05 августа 2009

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

0 голосов
/ 04 августа 2009

На первый взгляд, ваш код выглядит так, как будто он должен работать как положено.
Не могли бы вы показать нам пример окончательного текста, тип и результаты?
Когда я получаю неожиданные результаты, я обычно проверяю, какой запрос фактически использовался (в режиме отладки проверьте значение q), и использую этот запрос в Luke , чтобы увидеть, какие результаты он дает.

В моем коде я обычно использую хиты. Макс вместо хитов. Длина. Не знаю, в чем разница, но это то, что я заметил.

Кроме того, в качестве примечания, если остальная часть вашей программы не предписывает иное, вы можете захотеть проверить HashTable вместо ArrayList для вашего IdList, обычно он быстрее.

0 голосов
/ 04 августа 2009

Я согласен с Дэном, что это должно быть поведение по умолчанию Lucene. Если ваша реализация не работает таким образом, пожалуйста, добавьте детали, чтобы мы могли помочь вам диагностировать почему. Документация Lucene Similarity объясняет детали оценки Lucene, которая отвечает за порядок попаданий.

...