2009-11-04 3 views
4

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

package lucenebug; 

import java.util.Arrays; 
import java.util.List; 

import org.apache.lucene.analysis.SimpleAnalyzer; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.queryParser.QueryParser; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.ScoreDoc; 
import org.apache.lucene.search.TopDocs; 

public class Test { 
    private static final String TMP_LUCENEBUG_INDEX = "/tmp/lucenebug_index"; 

    public static void main(String[] args) throws Throwable { 
     SimpleAnalyzer analyzer = new SimpleAnalyzer(); 
     IndexWriter w = new IndexWriter(TMP_LUCENEBUG_INDEX, analyzer, true); 
     List<String> names = Arrays 
       .asList(new String[] { "the rolling stones", 
         "rolling stones (karaoke)", 
         "the rolling stones tribute", 
         "rolling stones tribute band", 
         "karaoke - the rolling stones" }); 
     try { 
      for (String name : names) { 
       System.out.println("#name: " + name); 
       Document doc = new Document(); 
       doc.add(new Field("name", name, Field.Store.YES, 
         Field.Index.TOKENIZED)); 
       w.addDocument(doc); 
      } 
      System.out.println("finished adding docs, total size: " 
        + w.docCount()); 

     } finally { 
      w.close(); 
     } 

     IndexSearcher s = new IndexSearcher(TMP_LUCENEBUG_INDEX); 
     QueryParser p = new QueryParser("name", analyzer); 
     Query q = p.parse("name:(rolling stones)"); 
     System.out.println("--------\nquery: " + q); 

     TopDocs topdocs = s.search(q, null, 10); 
     for (ScoreDoc sd : topdocs.scoreDocs) { 
      System.out.println("" + sd.score + "\t" 
        + s.doc(sd.doc).getField("name").stringValue()); 
     } 
    } 
} 

Выход я получаю от работы это:

finished adding docs, total size: 5 
-------- 
query: name:rolling name:stones 
0.578186 the rolling stones 
0.578186 rolling stones (karaoke) 
0.578186 the rolling stones tribute 
0.578186 rolling stones tribute band 
0.578186 karaoke - the rolling stones 

Я просто не могу понять, почему the rolling stones имеет такую ​​же значимость, как the rolling stones tribute. Согласно lucene's documentation, чем больше токенов имеет поле, тем меньше должен быть коэффициент нормировки, поэтому the rolling stones tribute должен иметь более низкий балл, чем the rolling stones.

Любые идеи?

+0

Какая версия Lucene вы используете (вы связываете API-документ 2.4)? В Lucene 2.9 оценки не возвращаются по умолчанию, вы должны предоставить TopFieldCollector: http://www.gossamer-threads.com/lists/lucene/java-user/86309 – digitalarbeiter

+0

@gossamer: я запустил тот же код против Lucene 2.3, 2.4 и 2.9. Те же результаты. –

ответ

5

коэффициент длины нормализации рассчитывается как 1/sqrt(numTerms) (Вы можете увидеть это в DefaultSimilarity

Этот результат не сохраняется в индексе непосредственно. Это значение умножается на значение наддува для поля, указанного. Конечный результат затем кодируется в 8 бит, как описано в Similarity.encodeNorm() Это кодирование с потерями, что означает мелкие детали теряются.

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

the rolling stones tribute a b c d e f g h i j k 

Это создаст достаточную разницу в значениях нормализации длины, которые вы могли видеть.

Теперь, если ваше поле имеет очень мало токенов в соответствии с примерами, которые вы использовали, вы можете установить значения повышения для документов/полей на основе вашей собственной формулы, что существенно повышает скорость для короткого поля. Кроме того, вы можете создать настраиваемое сходство и переопределить метод legthNorm().

+0

Правильно, 8-битная кодировка округляла «boost * lengthNorm» и вызывала проблему. Установка увеличения поля до 100 во время индексации - это достаточно простой способ для меня. @Shashikant Kore Спасибо! –

0

Я могу воспроизвести его на Lucene 2.3.1, но не знаю, почему это происходит.

Смежные вопросы