Lucene 使用

這幾天無聊,看了一下Lucene。使用如下:

1.下載Lucene,可以下載下來Lucene.net源碼。

2.建立一個Templucene工程中,並且在工程中添加lucene工程,或則是lucene引用。我的介面是這樣的。

3.建立目錄在debug下建立IndexDirectory,並且在這裡文件下建立2個文件夾,一個放要查詢的文檔temp,一個放生成的索引文件index。

4.建立處理類LuceneFunction,代碼如下:

 public  class LuceneFunction

    {

        private const string FILE_KEY_NAME = "filename";//文件名

        private const string CONTENT_KEY_NAME = "contents";//內容

        private const string CREATEDATE = "createDate";

        private const string TITLE = "title";//標題

        /// <summary>

        /// 目錄建立索引

        /// </summary>

        /// <param name="writer"></param>

        /// <param name="file"></param>

        public static void IndexDirectory(IndexWriter writer, io.FileInfo file)

        {

            if (io.Directory.Exists(file.FullName))

            {

                String[] files = io.Directory.GetFileSystemEntries(file.FullName);

                // an IO error could occur

                if (files != null)

                {

                    for (int i = 0; i < files.Length; i++)

                    {

                        IndexDirectory(writer, new io.FileInfo(files[i])); //这里是一个递归

                    }

                }

            }

            else 

            {

                //IndexFile(file, writer);

                AddHtmlDocument(file.FullName, writer);

            }

        }



        /// <summary>

        /// 單一個文件建立索引

        /// </summary>

        /// <param name="file"></param>

        /// <param name="writer"></param>

        private static void IndexFile(io.FileInfo file, IndexWriter writer)

        {

            Console.Out.WriteLine("adding " + file);

            try

            {

                Document doc = new Document();

                doc.Add(new Field(FILE_KEY_NAME, file.FullName, Field.Store.YES, Field.Index.ANALYZED));

                doc.Add(new Field(CONTENT_KEY_NAME, new io.StreamReader(file.FullName).ReadToEnd(), Field.Store.YES, Field.Index.ANALYZED));

                doc.Add(new Field(CREATEDATE,new io.FileInfo( file.FullName).LastWriteTime.ToString(), Field.Store.YES, Field.Index.ANALYZED));

                //doc.Add(new Field(CONTENT_KEY_NAME, new io.StreamReader(file.FullName),Field.TermVector.WITH_OFFSETS));



                writer.AddDocument(doc);

            }



            catch (io.FileNotFoundException fnfe)

            {



            }

        }



        public static void CreateIndex(string directory)

        {

            IndexWriter writer = new IndexWriter( new MMapDirectory(

              new System.IO.DirectoryInfo(@"IndexDirectory\index"))

                , new ChineseAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);

            IndexDirectory(writer, new System.IO.FileInfo(directory));

            writer.Optimize();

            writer.Dispose();

        }



        public static void SearchIndex(string queryString)

        {

            

            IndexSearcher indexSearcher = new IndexSearcher(new MMapDirectory(

              new System.IO.DirectoryInfo(@"IndexDirectory\index")));

            MultiFieldQueryParser QueryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30,

                new string[] { CONTENT_KEY_NAME, FILE_KEY_NAME }, new ChineseAnalyzer());

            //QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, CONTENT_KEY_NAME, analyzer);

            Query query = QueryParser.Parse(queryString);

            TopDocs docs = indexSearcher.Search(query,null,1000);

            for (int i = 0; i < docs.TotalHits; i++)

            {

                Document doc = indexSearcher.Doc(docs.ScoreDocs[i].Doc);//得到文檔的內容

                //Console.WriteLine(string.Format("文件名:{0} 內容:{1} 創建時間{2}", doc.Get(FILE_KEY_NAME),

                //    doc.Get(CONTENT_KEY_NAME), doc.Get(CREATEDATE)));

                Console.WriteLine(string.Format("文件名:{0}", doc.Get(FILE_KEY_NAME)));

            }

        }



        public static  void AddHtmlDocument(string path, IndexWriter writer)

        {

            string exname = io.Path.GetExtension(path);

            Document doc = new Document();



            string html;

            if (exname.ToLower() == ".html" || exname.ToLower() == ".htm" || exname.ToLower() == ".txt")

            {

                using (io.StreamReader sr = new io.StreamReader(path, System.Text.Encoding.Default))

                {

                    html = sr.ReadToEnd();

                }

            }

            else

            {

                using (io.StreamReader sr = new io.StreamReader(path, System.Text.Encoding.Unicode))

                {

                    html = sr.ReadToEnd();

                }

            }



            //int relativePathStartsAt = this.docRootDirectory.EndsWith("\\") ? this.docRootDirectory.Length : this.docRootDirectory.Length + 1;

            //string relativePath = path.Substring(relativePathStartsAt);

            //string title = io.Path.GetFileName(path);



            //判断若是网页则去标签否则不用

            if (exname.ToLower() == ".html" || exname.ToLower() == ".htm")

            {

                doc.Add(new Field(CONTENT_KEY_NAME, parseHtml(html), Field.Store.YES, Field.Index.ANALYZED));

                doc.Add(new Field(TITLE, getTitle(html), Field.Store.YES, Field.Index.ANALYZED));

            }

            else

            {

                doc.Add(new Field(CONTENT_KEY_NAME, html, Field.Store.YES, Field.Index.ANALYZED));

            }

            doc.Add(new Field(FILE_KEY_NAME, path, Field.Store.YES, Field.Index.NO));



            doc.Add(new Field(CREATEDATE, new io.FileInfo(path).LastWriteTime.ToString(), Field.Store.YES, Field.Index.ANALYZED));

            

            writer.AddDocument(doc);

        }



        /**/

        /// <summary>

        /// 去除网页中的标签

        /// </summary>

        /// <param name="html">网页</param>

        /// <returns>返回去除后的网页文本</returns>

        private static string parseHtml(string html)

        {

            string temp = Regex.Replace(html, "<[^>]*>", "");

            return temp.Replace(" ", " ");

        }

        /**/

        /// <summary>

        /// 获取网页标题

        /// </summary>

        /// <param name="html"></param>

        /// <returns></returns>

        private static string getTitle(string html)

        {

            Match m = Regex.Match(html, "<title>(.*)</title>");

            if (m.Groups.Count == 2)

                return m.Groups[1].Value;

            return "文档标题未知";

        }

    }

 5.使用:把要查詢的文檔放到temp下面。

代碼調用 :

       LuceneFunction.CreateIndex(@"IndexDirectory\temp");

            LuceneFunction.SearchIndex("Silverlight使用");

 第一步創建索引,第二部查詢。

6.對於一些使用對象的說明:

61.初始化索引對象:

      IndexWriter writer = new IndexWriter( new MMapDirectory(

              new System.IO.DirectoryInfo(@"IndexDirectory\index"))

                , new ChineseAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);

 第一個參數是目錄,即要對哪個目錄進行索引。ChineseAnalyzer是分詞類,這個使用的是中文分詞。

6.2建立索引對象后,給這個對象添加索引文件

              Document doc = new Document();

                doc.Add(new Field(FILE_KEY_NAME, file.FullName, Field.Store.YES, Field.Index.ANALYZED));

                doc.Add(new Field(CONTENT_KEY_NAME, new io.StreamReader(file.FullName).ReadToEnd(), Field.Store.YES, Field.Index.ANALYZED));

                doc.Add(new Field(CREATEDATE,new io.FileInfo( file.FullName).LastWriteTime.ToString(), Field.Store.YES, Field.Index.ANALYZED));

                //doc.Add(new Field(CONTENT_KEY_NAME, new io.StreamReader(file.FullName),Field.TermVector.WITH_OFFSETS));



                writer.AddDocument(doc);

 Document對象,相當於數據庫中的一條記錄。

就是把Document對象寫到索引中。

doc.Add(new Field(FILE_KEY_NAME, file.FullName, Field.Store.YES, Field.Index.ANALYZED));

是相當于給這個記錄的一個字段賦值。這裡是放文件名,作為key。

doc.Add(new Field(CONTENT_KEY_NAME, new io.StreamReader(file.FullName).ReadToEnd(), Field.Store.YES, Field.Index.ANALYZED));

是對文檔內容,加入到另一個字段,建立索引。

6.3 完成上面2部,那麼會在index目錄下會由文件生成,這樣這個文件的索引建立。已經為查詢做好準備了。

6.4 建立查詢對象

   IndexSearcher indexSearcher = new IndexSearcher(new MMapDirectory(
              new System.IO.DirectoryInfo(@"IndexDirectory\index")));

其中目錄指向,剛才生成索引的位置。

  MultiFieldQueryParser QueryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30,

                new string[] { CONTENT_KEY_NAME, FILE_KEY_NAME }, new ChineseAnalyzer());

 指定要查詢的欄位。並且用中文分詞。

Query query = QueryParser.Parse(queryString);

 生成查詢條件。

       TopDocs docs = indexSearcher.Search(query,null,1000);

            for (int i = 0; i < docs.TotalHits; i++)

            {

                Document doc = indexSearcher.Doc(docs.ScoreDocs[i].Doc);//得到文檔的內容

                //Console.WriteLine(string.Format("文件名:{0} 內容:{1} 創建時間{2}", doc.Get(FILE_KEY_NAME),

                //    doc.Get(CONTENT_KEY_NAME), doc.Get(CREATEDATE)));

                Console.WriteLine(string.Format("文件名:{0}", doc.Get(FILE_KEY_NAME)));

            }

 開始查詢。並且得到結果 。docs,對應這個查詢,只是查詢出索引,並沒有實際記載內容。

Document doc = indexSearcher.Doc(docs.ScoreDocs[i].Doc);
這一句,才把要的結果查詢出來了。放到Documen中,這個Documen和最上面寫入索引用的是一樣的。Documen就是查詢得到的內容。
doc.Get(FILE_KEY_NAME)是得到Document中相應欄位的數值。
7.對應html文件,可以對原有文件如果查到內容,會對相應內容,進行變色。這個就不做解釋了。
8.對於所有的文檔,只要能轉換成txt文件就都可以查詢了了。如果txt html doc pdf等。

 

 

你可能感兴趣的:(Lucene)