• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            為生存而奔跑

               :: 首頁 :: 聯系 :: 聚合  :: 管理
              271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

            留言簿(5)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 326969
            • 排名 - 74

            最新評論

            閱讀排行榜

            評論排行榜

            本文僅記錄一些簡單的使用方法,供初學者參考。
            以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下載。

            1. 基本應用
            using System;
            using System.Collections.Generic;
            using System.Text;
            using Lucene.Net;
            using Lucene.Net.Analysis;
            using Lucene.Net.Analysis.Standard;
            using Lucene.Net.Documents;
            using Lucene.Net.Index;
            using Lucene.Net.QueryParsers;
            using Lucene.Net.Search;
            using Lucene.Net.Store;
            using Lucene.Net.Util;

            namespace ConsoleApplication1.Lucene
            {
              public class LuceneTest
              {
                private const string FieldName = "name";
                private const string FieldValue = "value";

                private Directory directory = new RAMDirectory();
                private Analyzer analyzer = new StandardAnalyzer();

                public LuceneTest()
                {
                }

                private void Index()
                {
                  IndexWriter writer = new IndexWriter(directory, analyzer, true);
                  writer.maxFieldLength = 1000;
                  
                  for (int i = 1; i <= 100; i++)
                  {
                    Document document = new Document();

                    document.Add(new Field(FieldName, "name" + i, Field.Store.YES, Field.Index.UN_TOKENIZED));
                    document.Add(new Field(FieldValue, "Hello, World!", Field.Store.YES, Field.Index.TOKENIZED));

                    writer.AddDocument(document);
                  }

                  writer.Optimize();
                  writer.Close();
                }

                private void Search()
                {
                  Query query = QueryParser.Parse("name*", FieldName, analyzer);

                  IndexSearcher searcher = new IndexSearcher(directory);

                  Hits hits = searcher.Search(query);
                  
                  Console.WriteLine("符合條件記錄:{0}; 索引庫記錄總數:{1}", hits.Length(), searcher.Reader.NumDocs());
                  for (int i = 0; i < hits.Length(); i++)
                  {
                    int docId = hits.Id(i);
                    string name = hits.Doc(i).Get(FieldName);
                    string value = hits.Doc(i).Get(FieldValue);
                    float score = hits.Score(i);

                    Console.WriteLine("{0}: DocId:{1}; Name:{2}; Value:{3}; Score:{4}", 
                      i + 1, docId, name, value, score);
                  }

                  searcher.Close();
                }
              }
            }

            除了 RAMDirectory,還可以使用 FSDirectory。(注意 FSDirectory.GetDirectory 的 create 參數,為 true 時將刪除已有索引庫文件,可以通過 IndexReader.IndexExists() 方法判斷。)

            從指定目錄打開已有索引庫。
            private Directory directory = FSDirectory.GetDirectory("c:\index", false);

            將索引庫載入內存,以提高搜索速度。
            private Directory directory = new RAMDirectory(FSDirectory.GetDirectory(@"c:\index", false));
            //或
            //private Directory directory = new RAMDirectory(c:\index");

            2. 多字段搜索

            使用 MultiFieldQueryParser 可以指定多個搜索字段。
            Query query = MultiFieldQueryParser.Parse("name*", new string[] { FieldName, FieldValue }, analyzer);

            IndexReader reader = IndexReader.Open(directory);
            IndexSearcher searcher = new IndexSearcher(reader);
            Hits hits = searcher.Search(query);

            3. 多條件搜索

            除了使用 QueryParser.Parse 分解復雜的搜索語法外,還可以通過組合多個 Query 來達到目的。
            Query query1 = new TermQuery(new Term(FieldValue, "name1")); // 詞語搜索
            Query query2 = new WildcardQuery(new Term(FieldName, "name*")); // 通配符 
            //Query query3 = new PrefixQuery(new Term(FieldName, "name1")); // 字段搜索 Field:Keyword,自動在結尾添加 *
            //Query query4 = new RangeQuery(new Term(FieldNumber, NumberTools.LongToString(11L)), new Term(FieldNumber, NumberTools.LongToString(13L)), true); // 范圍搜索
            //Query query5 = new FilteredQuery(query, filter); // 帶過濾條件的搜索
                  
            BooleanQuery query = new BooleanQuery();
            query.Add(query1, BooleanClause.Occur.MUST);
            query.Add(query2, BooleanClause.Occur.MUST);

            IndexSearcher searcher = new IndexSearcher(reader);
            Hits hits = searcher.Search(query);

            4. 設置權重

            可以給 Document 和 Field 增加權重(Boost),使其在搜索結果排名更加靠前。缺省情況下,搜索結果以 Document.Score 作為排序依據,該數值越大排名越靠前。Boost 缺省值為 1。
            Score = Score * Boost

            通過上面的公式,我們就可以設置不同的權重來影響排名。

            如下面的例子中根據 VIP 級別設定不同的權重。
            Document document = new Document();
            switch (vip)
            {
              case VIP.Gold: document.SetBoost(2F); break;
              case VIP.Argentine: document.SetBoost(1.5F); break;
            }

            只要 Boost 足夠大,那么就可以讓某個命中結果永遠排第一位,這就是百度等網站的"收費排名"業務。明顯有失公平,鄙視一把。 [no] 

            5. 排序

            通過 SortField 的構造參數,我們可以設置排序字段,排序條件,以及倒排。
            Sort sort = new Sort(new SortField(FieldName, SortField.DOC, false));

            IndexSearcher searcher = new IndexSearcher(reader);
            Hits hits = searcher.Search(query, sort);

            排序對搜索速度影響還是很大的,盡可能不要使用多個排序條件。

            6. 過濾

            使用 Filter 對搜索結果進行過濾,可以獲得更小范圍內更精確的結果。

            舉個例子,我們搜索上架時間在 2005-10-1 到 2005-10-30 之間的商品。
            對于日期時間,我們需要轉換一下才能添加到索引庫,同時還必須是索引字段。
            // index
            document.Add(FieldDate, DateField.DateToString(date), Field.Store.YES, Field.Index.UN_TOKENIZED);

            //...

            // search
            Filter filter = new DateFilter(FieldDate, DateTime.Parse("2005-10-1"), DateTime.Parse("2005-10-30"));
            Hits hits = searcher.Search(query, filter);

            除了日期時間,還可以使用整數。比如搜索價格在 100 ~ 200 之間的商品。
            Lucene.Net NumberTools 對于數字進行了補位處理,如果需要使用浮點數可以自己參考源碼進行。
            // index
            document.Add(new Field(FieldNumber, NumberTools.LongToString((long)price), Field.Store.YES, Field.Index.UN_TOKENIZED));

            //...

            // search
            Filter filter = new RangeFilter(FieldNumber, NumberTools.LongToString(100L), NumberTools.LongToString(200L), true, true);
            Hits hits = searcher.Search(query, filter);

            使用 Query 作為過濾條件。
            QueryFilter filter = new QueryFilter(QueryParser.Parse("name2", FieldValue, analyzer));

            我們還可以使用 FilteredQuery 進行多條件過濾。
            Filter filter = new DateFilter(FieldDate, DateTime.Parse("2005-10-10"), DateTime.Parse("2005-10-15"));
            Filter filter2 = new RangeFilter(FieldNumber, NumberTools.LongToString(11L), NumberTools.LongToString(13L), true, true);

            Query query = QueryParser.Parse("name*", FieldName, analyzer);
            query = new FilteredQuery(query, filter);
            query = new FilteredQuery(query, filter2);

            IndexSearcher searcher = new IndexSearcher(reader);
            Hits hits = searcher.Search(query);

            7. 分布搜索

            我們可以使用 MultiReader 或 MultiSearcher 搜索多個索引庫。
            MultiReader reader = new MultiReader(new IndexReader[] { IndexReader.Open(@"c:\index"), IndexReader.Open(@"\\server\index") });
            IndexSearcher searcher = new IndexSearcher(reader);
            Hits hits = searcher.Search(query);


            IndexSearcher searcher1 = new IndexSearcher(reader1);
            IndexSearcher searcher2 = new IndexSearcher(reader2);
            MultiSearcher searcher = new MultiSearcher(new Searchable[] { searcher1, searcher2 });
            Hits hits = searcher.Search(query);

            還可以使用 ParallelMultiSearcher 進行多線程并行搜索。

            8. 合并索引庫

            將 directory1 合并到 directory2 中。
            Directory directory1 = FSDirectory.GetDirectory("index1", false);
            Directory directory2 = FSDirectory.GetDirectory("index2", false);

            IndexWriter writer = new IndexWriter(directory2, analyzer, false);
            writer.AddIndexes(new Directory[] { directory });
            Console.WriteLine(writer.DocCount());
            writer.Close();

            9. 顯示搜索語法字符串

            我們組合了很多種搜索條件,或許想看看與其對等的搜索語法串是什么樣的。
            BooleanQuery query = new BooleanQuery();
            query.Add(query1, true, false);
            query.Add(query2, true, false);
            //...

            Console.WriteLine("Syntax: {0}", query.ToString());

            輸出:
            Syntax: +(name:name* value:name*) +number:[0000000000000000b TO 0000000000000000d]

            呵呵,就這么簡單。

            10. 操作索引庫

            刪除 (軟刪除,僅添加了刪除標記。調用 IndexWriter.Optimize() 后真正刪除。)
            IndexReader reader = IndexReader.Open(directory);

            // 刪除指定序號(DocId)的 Document。
            reader.Delete(123);

            // 刪除包含指定 Term 的 Document。
            reader.Delete(new Term(FieldValue, "Hello"));

            // 恢復軟刪除。
            reader.UndeleteAll();

            reader.Close();

            增量更新 (只需將 create 參數設為 false,即可往現有索引庫添加新數據。)
            Directory directory = FSDirectory.GetDirectory("index", false);
            IndexWriter writer = new IndexWriter(directory, analyzer, false);
            writer.AddDocument(doc1);
            writer.AddDocument(doc2);
            writer.Optimize();
            writer.Close();

            11. 優化

            批量向 FSDirectory 增加索引時,增大合并因子(mergeFactor )和最小文檔合并數(minMergeDocs)有助于提高性能,減少索引時間。
            IndexWriter writer = new IndexWriter(directory, analyzer, true);

            writer.maxFieldLength = 1000; // 字段最大長度
            writer.mergeFactor = 1000;
            writer.minMergeDocs = 1000;

            for (int i = 0; i < 10000; i++)
            {
              // Add Documentes...
            }

            writer.Optimize();
            writer.Close();

            相關參數說明 


            轉自《深入 Lucene 索引機制

            利用 Lucene,在創建索引的工程中你可以充分利用機器的硬件資源來提高索引的效率。當你需要索引大量的文件時,你會注意到索引過程的瓶頸是在往磁盤上寫索引文件的過程中。為了解決這個問題, Lucene 在內存中持有一塊緩沖區。但我們如何控制 Lucene 的緩沖區呢?幸運的是,Lucene 的類 IndexWriter 提供了三個參數用來調整緩沖區的大小以及往磁盤上寫索引文件的頻率。

            1.合并因子 (mergeFactor)

            這個參數決定了在 Lucene 的一個索引塊中可以存放多少文檔以及把磁盤上的索引塊合并成一個大的索引塊的頻率。比如,如果合并因子的值是 10,那么當內存中的文檔數達到 10 的時候所有的文檔都必須寫到磁盤上的一個新的索引塊中。并且,如果磁盤上的索引塊的隔數達到 10 的話,這 10 個索引塊會被合并成一個新的索引塊。這個參數的默認值是 10,如果需要索引的文檔數非常多的話這個值將是非常不合適的。對批處理的索引來講,為這個參數賦一個比較大的值會得到比較好的索引效果。

            2.最小合并文檔數 (minMergeDocs)

            這個參數也會影響索引的性能。它決定了內存中的文檔數至少達到多少才能將它們寫回磁盤。這個參數的默認值是10,如果你有足夠的內存,那么將這個值盡量設的比較大一些將會顯著的提高索引性能。

            3.最大合并文檔數 (maxMergeDocs)

            這個參數決定了一個索引塊中的最大的文檔數。它的默認值是 Integer.MAX_VALUE,將這個參數設置為比較大的值可以提高索引效率和檢索速度,由于該參數的默認值是整型的最大值,所以我們一般不需要改動這個參數。


            -------------------迷糊中的分割線-----------------------------

            Lucene 相關資源:

            1. Lucene 官方網站
            2. Apache Lucene
            3. Lucene FAQ
            4. Lucene.Net
            5. Lucene API (Java)
            6. DotLucene
            7. Luke - Lucene Index Toolbox
            8. Nutch
            9. LUCENE.COM.CN 中國
            10. Compass
            11. 實戰 Lucene,第 1 部分: 初識 Lucene
            12. 深入 Lucene 索引機制
            posted on 2010-03-21 13:49 baby-fly 閱讀(515) 評論(0)  編輯 收藏 引用 所屬分類: Information Retrival / Data Mining
            久久久中文字幕日本| 久久亚洲欧美国产精品| 久久人人爽人人人人片av| 久久久91精品国产一区二区三区| 久久久久一区二区三区| 久久久久亚洲AV无码专区首JN | 久久人妻少妇嫩草AV无码专区| 欧美久久天天综合香蕉伊| 久久国产精品免费一区| 丁香五月综合久久激情| 日本精品一区二区久久久| 中文精品久久久久国产网址| 无码人妻久久一区二区三区蜜桃| 久久无码一区二区三区少妇| 欧美粉嫩小泬久久久久久久| 伊人精品久久久久7777| 99久久国产精品免费一区二区| 亚洲va中文字幕无码久久| 久久久久人妻一区精品色| 国产99久久精品一区二区| 精品国产乱码久久久久久浪潮| 伊人色综合久久天天网| 无码人妻少妇久久中文字幕蜜桃| 91视频国产91久久久| 国产毛片久久久久久国产毛片 | 久久99国产综合精品| 久久这里只精品国产99热| 欧美久久综合九色综合| 免费久久人人爽人人爽av| 久久99精品久久久久久久久久| 精品无码人妻久久久久久| 精品国产乱码久久久久软件| 精品久久久久久国产| 无码精品久久一区二区三区| 久久ZYZ资源站无码中文动漫 | 精品久久久久中文字幕一区| 偷窥少妇久久久久久久久| 成人亚洲欧美久久久久| 一本一道久久综合狠狠老| 久久久久99精品成人片| 99久久99久久精品免费看蜜桃|