Betaノート-検索エンジンの設計と実現(1):Lucene.Netを使用してインデックスと中国語の分詞を確立する

10893 ワード

寝室に帰る前に数分かけて、私の現在の学霸検索エンジンの構築ツール:Lucene.Net盤古分詞の使用を書いてください.
1.概要
Lucene.Netは優秀なJavaプラットフォームの下のオープンソース検索エンジンソリューションLuceneの.Netバージョンで、学霸プロジェクトでは2.9.2バージョンを使用しています.
盤古分詞はオープンソースの中国語分詞ソフトで、分詞速度が速く、カスタム辞書と停詞設定をサポートし、Lucene.Netとシームレスに統合することができ、学霸では最新の2.3.3バージョンが使用されている.
2. Lucene.Net HelloWorld
テストの過程で、Luceneの複数の異なるバージョンを試してみましたが、異なるバージョンのLuceneの各操作文法の違いが大きく、異なるバージョンのインデックスが共有できないことは理解できません.以下、2.9.2版を例にとると、最新3.0.3版はそれと大きく異なり、最新版を使わないのは、盤古の分詞に合わせるためだ.
まず、いくつかの入門リソースを提供します.
  • How to get started with Lucene.Net
  • The Main Concepts
  • Your First Application
  • Dissecting Storage Documents and Fields
  • Lucene - or how I stopped worrying and learned to love unstructured data
  • How Subtext Lucene.Net index is structured

  •  2.1インデックスディレクトリの作成
    Lucene.Netにデータを入力する前に、まずインデックスの保存パスを設定する必要があります.Lucene.Netはディスクインデックスとメモリインデックスをサポートします.ここでは、ディスクインデックスを例に挙げます.
    Directory directory = FSDirectory.GetDirectory("LuceneIndex");

    2.2アナライザの構築
    アナライザは、データを分詞するために使用され、後続の逆インデックスの作成を容易にします.
    Analyzer analyzer = new StandardAnalyzer();
    
    

    2.3 IndexWriterの作成
    IndexWriterはDocumentをインデックスファイルに書き込み、逆インデックスを作成するために使用します.
    IndexWriter writer = new IndexWriter(directory, analyzer); 

    // addDocs(writer);
    writer.Optimize(); writer.Commit(); writer.Close();

    addDocs(writer)のメソッドコードは次のとおりです.
                List<Question> qlist = new QuestionManager().GetQuestions(1);
    
                foreach (Question q in qlist)
    
                {
    
                    Lucene.Net.Documents.Document doc = new Lucene.Net.Documents.Document();
    
                    doc.Add(new Field("qid", q.Id.ToString(), Field.Store.YES, Field.Index.NO));
    
                    // doc.Add(new Field("tags",q.Tags))
    
                    doc.Add(new Field("title", q.Title, Field.Store.YES, Field.Index.ANALYZED));
    
                    doc.Add(new Field("content", q.Content, Field.Store.YES, Field.Index.ANALYZED));
    
                    doc.Add(new Field("created", q.PostDateTime.ToShortDateString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
    
                    doc.Add(new Field("repiles", q.Replies.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
    
                    doc.Add(new Field("views", q.Views.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
    
                    writer.AddDocument(doc);
    
                }

    2.4検索
    インデックスが作成され、検索を開始します.まずSearcherを初期化し、QueryParserを使用してQueryStringを解析処理し、Searcherオブジェクトをコミットし、返された結果をHitsに保存します.
    IndexSearcher searcher = new IndexSearcher(directory,false);
    
    QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "title", new PanGuAnalyzer(true));
    
    //Supply conditions
    
    string keys = "flash C++";
    
    keys = GetKeyWordsSplitBySpace(keys, new PanGuTokenizer());
    
    Query query = parser.Parse(keys);
    
    
    
    //Do the search
    
    Hits hits = searcher.Search(query);
    
    ScoreDoc[] result = searcher.Search(query, null, 100).scoreDocs;
    
    for (int i = 0; i < result.Length; i++)
    
         Console.WriteLine(searcher.Doc(result[i].doc).Get("title"));

    最後にリソースを閉じることを忘れないでください
    analyzer.Close();
    
    writer.Close();
    
    directory.Close();

    3.盤古分詞の統合
    テストの时、私は公式コンパイルのバージョンを使ってLucene.Netの中に统合することを発见して、検索结果を得ることができなくて、公式blogの中で问题に対して说明しました(http://www.cnblogs.com/eaglet/archive/2010/05/12/1733581.html#2529278)、しかし、私は公式コンパイルのバージョンを使って依然として検索结果を得ることができないことを発见して、仕方なくソースコードをダウンロードして自分で最新の2.3.3バージョンをコンパイルするしかありません.
    統合プロセスは比較的簡単で、StandardAnalyzerをPanGuanalyzerに置き換えるとよい.
     PanGu.Segment.Init();             Directory directory = FSDirectory.GetDirectory("LuceneIndex");
    
                //Analyzer analyzer = new StandardAnalyzer();
    
                Analyzer analyzer =new PanGuAnalyzer();             IndexWriter writer = new IndexWriter(directory, analyzer); 
    
    
    
                //addDocs(writer);
    
                writer.Optimize();
    
                writer.Commit();
    
                writer.Close();
    
    
    
                IndexSearcher searcher = new IndexSearcher(directory,false);
    
                //QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29,"title", analyzer);
    
                QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "title", new PanGuAnalyzer(true));
    
                //Supply conditions
    
                string keys = "flash C++";
    
                keys = GetKeyWordsSplitBySpace(keys, new PanGuTokenizer());
    
                Query query = parser.Parse(keys);
    
    
    
                //Do the search
    
                Hits hits = searcher.Search(query);
    
                ScoreDoc[] result = searcher.Search(query, null, 100).scoreDocs;
    
                for (int i = 0; i < result.Length; i++)
    
                    Console.WriteLine(searcher.Doc(result[i].doc).Get("title"));
    
    
    
                analyzer.Close();
    
                writer.Close();
    
                directory.Close();