Lucene.Net 設定索引權重

摘要:Lucene.Net 設定索引權重

當我們在使用檢索功能時 , 會發現光是把東西搜出來是不夠的 ,  

 

還必須能夠對檢索的結果進行排序 , 將與搜尋的關鍵字最相關的內容送到使用者面前 ,

 

這樣子對使用者來說會是比較好的結果 ,  

 

而 Lucene.Net 文件的得分主要由 4 個部份來決定  , tf ( 詞頻 ) , idf ( 反轉文件頻率 ) , boost ( 提升 ) , lengthNorm ( 長度 ) ,

 

下面的 sample 中主要會提到的是  boost 的部分 , 而在結果的後面輸出了每一個結果的得分 

 

Step 1 : Build Index 

 


private void BuildIndex()
    {
        DirectoryInfo dirInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data");
        FSDirectory dir = FSDirectory.Open(dirInfo);
        IndexWriter iw = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED);
        Document doc1 = new Document();
        Document doc2 = new Document();
        Document doc3 = new Document();
        

        Field f1 = new Field("bookname", "ab", Field.Store.YES, Field.Index.ANALYZED);
        Field f2 = new Field("bookname", "ab bc", Field.Store.YES, Field.Index.ANALYZED);
        Field f3 = new Field("bookname", "ab bc cd", Field.Store.YES, Field.Index.ANALYZED);

        f3.Boost = 2;
        

        doc1.Add(f1);
        doc2.Add(f2);
        doc3.Add(f3);

        iw.AddDocument(doc1);
        iw.AddDocument(doc2);
        iw.AddDocument(doc3);
      

        iw.Optimize();
        iw.Commit();
        iw.Close();

    }

 

在上面的範例中我們對 Filed 提升了它的 boost , 但是我們也可以對 Document  提升它的 boost 

 

 

Step 2 : Search


private void SearchIndex(string keyword)
    {
        DirectoryInfo dirInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data");
        FSDirectory dir = FSDirectory.Open(dirInfo);
        IndexSearcher search = new IndexSearcher(dir, true);

        QueryParser qp = new QueryParser(Version.LUCENE_30, "bookname", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30));

        TermQuery q = new TermQuery(new Term("bookname", keyword));

        var hits = search.Search(q,10).ScoreDocs;

        foreach (var res in hits)
        {
            Response.Write(string.Format("bookname:{0} / score:{1}", 
                                        search.Doc(res.Doc).Get("bookname").ToString() 
                                        ,res.Score + "
"));
            
        }
    }

 

Step 3 : 執行

 


BuildIndex();
SearchIndex("bc");

 

Result : 

若 f 3  不加上 boost  的話 , ab bc bc 目前是排序最前面

 


bookname:ab bc bc / score:0.5036848
bookname:ab bc / score:0.4451987
bookname:ab bc cd / score:0.356159

 

若 f 3 加上 boost 的話 

 

ab bc cd 變成第一順位了

 


bookname:ab bc cd / score:0.7123179
bookname:ab bc bc / score:0.5036848
bookname:ab bc / score:0.4451987

 

在 Lucene.Net 中 , boost 一般預設為  1.0 , 當某文件的 boost 大於 1.0 後 , 

 

所有文件的 boost 值均會除以這個最大值, 這樣一來每個文件會獲得一個小於

 

1.0 的值做為新的 boost 值