Lucene.Netサイト内検索3—最も簡単な検索エンジンコード


Lucene.Netコアクラスの概要


作成したインデックスのコードを実行してから、各クラスの役割を説明し、コードを暗記する必要はありません.
(*)Directoryはインデックスファイル(Lucene.netでユーザが投げたデータを保存する場所)が保存されている場所を表し、抽象クラス、2つのサブクラスFSDirectory(ファイル中)、RAM Directory(内蔵中)である.使うときはIOのDirectoryと混同しないでください.
FSDirectoryを作成する方法、FSDirectory=FSDirectory.Open(new DirectoryInfo(indexPath)、new NativeFSLockFactory()、pathインデックスのフォルダパス
IndexReaderインデックスを読み込むクラス、IndexWriterを書くクラス.
IndexReaderの静的メソッドbool IndexExists(Directory Directory)は、ディレクトリdirectoryがインデックスディレクトリであるかどうかを判断します.IndexWriterのbool IsLocked(Directory directory)は、ディレクトリがロックされているかどうかを判断し、ディレクトリを書く前にディレクトリをロックします.2つのIndexWriterは同時にインデックスファイルを書くことができません.IndexWriterは書き込み操作時に自動的にロックされ、close時に自動的にロックが解除されます.IndexWriter.Unlockメソッドは手動でロックを解除します(たとえばclose IndexWriterプログラムがクラッシュし、ロックされ続ける可能性があります).

索引の作成


コンストラクション関数:IndexWriter(Directorydir,Analyzer a,bool create,MaxFieldLength mfl)IndexWriterが入力をインデックスに書き込む場合、Lucene.Netは,書き込まれたファイルを指定した分詞器で文章分詞(検索時に調べるのが速い)し,インデックスファイルに単語を入れる.
void AddDocument(Document doc)は、インデックスにドキュメント(Insert)を追加します.Documentクラスは、インデックスするドキュメント(記事)、最も重要なメソッドAdd(Field field)を表し、ドキュメントにフィールドを追加します.Documentはドキュメントで、Fieldはフィールド(プロパティ)です.Documentはレコードに相当し、Fieldはフィールドに相当します.
Fieldクラスのコンストラクション関数Field(string name,string value,Field.Store store,Field.Indexindexindex,Field.TermVectortermVector):nameはフィールド名を表します.valueはフィールド値を表します.
storeはvalue値を格納するか否かを示し、オプション値Field.Store.YESストレージ、Field.Store.NO保存しないStore.COMPRESS圧縮ストレージ;デフォルトでは、分詞の後の単語の山だけが保存され、分詞の前の内容は保存されず、検索時に分詞の後のものに基づいて原文を復元することはできません.そのため、原文(例えば、文章の本文)を表示するには、保存を設定する必要があります.
Indexはインデックスを作成する方法を示し、オプションの値Field.Index. NOT_ANALYZED、インデックスを作成しない、Field.Index. ANALYZED、インデックスを作成する;インデックスを作成するフィールドのみが比較的良い取得ができます.死体を砕くかどうか!このフィールドに従って「全文検索」を行う必要があるかどうか.
termVectorは、索引語間の距離をどのように保存するかを表します.「北京は皆さんを歓迎します」、索引の中でどのように“北京”と“みんな”の間の“どれだけの単語を隔てます”を保存します.一定距離内の単語だけを検索するのに便利です.
なぜ投稿のurlをFieldにするのか、表示を検索するときに先に投稿アドレスを取り出してハイパーリンクを構築するため、Field.Store.YES;一般的にurlを検索する必要はないのでField.Index.NOT_ANALYZED .「紅楼夢」に基づいて構築された「語:ページ数」紙は、構築が完了すると原文「紅楼夢」を捨てることができる.
ケース:1000~1100番の投稿をインデックスします.「例やドキュメントが読めるように、少し修正すれば自分のニーズを実現できます」.基礎知識のほか、サードパーティ開発パッケージは「読め、改めればいい」
ネームスペースの導入:
using Lucene.Net.Store;
using System.IO;
using Lucene.Net.Index;
using Lucene.Net.Analysis.PanGu;
using Lucene.Net.Documents;
using Lucene.Net.Search;

1、データの索引付け
            string indexPath = @"C:\1017index";//               ,     。
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());
            bool isUpdate = IndexReader.IndexExists(directory);//         
            if (isUpdate)
            {
                //         (             ),     
                //Lucene.Net            , close        
                //       ,              
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);//un-  。    
                }
            }
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);
            for (int i = 1000; i < 1100; i++)
            {
                string txt = File.ReadAllText(@"D:\    \  \    \    \2011-10-17   \  \" + i + ".txt");
                Document document = new Document();//  Document       
                document.Add(new Field("id", i.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                //  Document        (  ),           ,   string  
                //Field.Store.YES            ,      ,            
                //             Field.Index. ANALYZED
                document.Add(new Field("msg", txt, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
                //      
                writer.DeleteDocuments(new Term("id", i.ToString()));//       //delete from t where id=i
                //        0 
                writer.AddDocument(document);//        
            }
            writer.Close();
            directory.Close();//    Close,         

2、検索コード
            string indexPath = @"C:\1017index";

            string kw = TextBox1.Text;
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory());
            IndexReader reader = IndexReader.Open(directory, true);
            IndexSearcher searcher = new IndexSearcher(reader);
            PhraseQuery query = new PhraseQuery();//    
            query.Add(new Term("msg", kw));//where contains("msg",kw)
            //foreach (string word in kw.Split(' '))//    ,      ,        “      ”
            //{
            //    query.Add(new Term("msg", word));//contains("msg",word)
            //}
            query.SetSlop(100);//        100(   )        ,             
            TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);//         
            searcher.Search(query, null, collector);//  query          ,      collector
            //collector.GetTotalHits()      
            ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;//         m   n    

            List list = new List();
            for (int i = 0; i < docs.Length; i++)//      
            {
                int docId = docs[i].doc;//     id。  Document       (DataSet DataReader   )
                //         id,          
                Document doc = searcher.Doc(docId);//  id    。     Document,      Document
                //Console.WriteLine(doc.Get("id"));
                //Console.WriteLine(doc.Get("msg"));
                SearchResult result = new SearchResult();
                result.Id = Convert.ToInt32(doc.Get("id"));
                result.Msg = doc.Get("msg");//   Field.Store.YES      Get   
                list.Add(result);
            }

            Repeater1.DataSource = list;
            Repeater1.DataBind();
 
  

aspx代码: