當前位置:編程學習大全網 - 源碼下載 - 如何讀取lucene索引數據

如何讀取lucene索引數據

我們壹步壹步來看。這裏建設已經有實現建好索引,存放在index目錄下。好,要讀索引,總得先生成壹個讀索引器(即Lucene中IndexReader的實例)。好,寫下面的程序(程序為C#程序,本文使用DotLucene)。

IndexReader reader;

問題出來了,IndexReader是壹個abstract類,不能實例化。那好,換派生類試試看。找到IndexReader的兩個孩子——SegmentReader和MultiReader。用哪個呢?無論是哪個都需要壹大堆參數(我是頗費了周折才搞清楚它們的用途,後面再解釋),似乎想用Lucene的索引數據不是那麽容易啊。通過跟蹤代碼和查閱文檔,我終於找到使用IndexReader的鑰匙。原來IndexReader有壹個“工廠模式”的static interface——IndexReader.Open。定義如下:

#0001 public static IndexReader Open(System.String path)

#0002 public static IndexReader Open(System.IO.FileInfo path)

#0003 public static IndexReader Open(Directory directory)

#0004 private static IndexReader Open(Directory directory, bool closeDirectory)

其中有三個是public的接口,可供調用。打開壹個索引,就是這麽簡單:

#0001 IndexReader reader = IndexReader.Open(index);

實際上,這個打開索引經歷了這樣的壹個過程:

#0001 SegmentInfos infos = new SegmentInfos();

#0002 Directory directory = FSDirectory.GetDirectory(index, false);

#0003 infos.Read(directory);

#0004 bool closeDirectory = false;

#0005 if (infos.Count == 1)

#0006 {

#0007 // index is optimized

#0008 return new SegmentReader(infos, infos.Info(0), closeDirectory);

#0009 }

#0010 else

#0011 {

#0012 IndexReader[] readers = new IndexReader[infos.Count];

#0013 for (int i = 0; i < infos.Count; i++)

#0014 readers[i] = new SegmentReader(infos.Info(i));

#0015 return new MultiReader(directory, infos, closeDirectory, readers);

#0016 }

首先要讀入索引的段信息(segment information, #0001~#0003),然後看壹下有幾個段:如果只有壹個,那麽可能是優化過的,直接讀取這壹個段就可以(#0008);否則需要壹次讀入各個段(#0013~#0014),然後再拼成壹個MultiReader(#0015)。打開索引文件的過程就是這樣。

接下來我們要看看如何讀取信息了。用下面這段代碼來說明。

#0001 public static void PrintIndex(IndexReader reader)

#0002 {

#0003 //顯示有多少個document

#0004 System.Console.WriteLine(reader + "\tNumDocs = " + reader.NumDocs());

#0005 for (int i = 0; i < reader.NumDocs(); i++)

#0006 {

#0007 System.Console.WriteLine(reader.Document(i));

#0008 }

#0009

#0010 //枚舉term,獲得<document, term freq, position* >信息

#0011 TermEnum termEnum = reader.Terms();

#0012 while (termEnum.Next())

#0013 {

#0014 System.Console.Write(termEnum.Term());

#0015 System.Console.WriteLine("\tDocFreq=" + termEnum.DocFreq());

#0016

#0017 TermPositions termPositions = reader.TermPositions(termEnum.Term());

#0018 int i = 0;

#0019 int j = 0;

#0020 while (termPositions.Next())

#0021 {

#0022 System.Console.WriteLine((i++) + "->" + " DocNo:" + termPositions.Doc() + ", Freq:" + termPositions.Freq());

#0023 for (j = 0; j < termPositions.Freq(); j++)

#0024 System.Console.Write("[" + termPositions.NextPosition() + "]");

#0025 System.Console.WriteLine();

#0026 }

#0027

#0028 //直接獲取 <term freq, document> 的信息

#0029 TermDocs termDocs = reader.TermDocs(termEnum.Term());

#0030 while (termDocs.Next())

#0031 {

#0032 System.Console.WriteLine((i++) + "->" + " DocNo:" + termDocs.Doc() + ", Freq:" + termDocs.Freq());

#0033 }

#0034 }

#0035

#0036 // FieldInfos fieldInfos = reader.fieldInfos;

#0037 // FieldInfo pathFieldInfo = fieldInfos.FieldInfo("path");

#0038

#0039 //顯示 term frequency vector

#0040 for (int i = 0; i < reader.NumDocs(); i++)

#0041 {

#0042 //對contents的token之後的term存於了TermFreqVector

#0043 TermFreqVector termFreqVector = reader.GetTermFreqVector(i, "contents");

#0044

#0045 if (termFreqVector == null)

#0046 {

#0047 System.Console.WriteLine("termFreqVector is null.");

#0048 continue;

#0049 }

#0050

#0051 String fieldName = termFreqVector.GetField();

#0052 String[] terms = termFreqVector.GetTerms();

#0053 int[] frequences = termFreqVector.GetTermFrequencies();

#0054

#0055 System.Console.Write("FieldName:" + fieldName);

#0056 for (int j = 0; j < terms.Length; j++)

#0057 {

#0058 System.Console.Write("[" + terms[j] + ":" + frequences[j] + "]");

#0059 }

#0060 System.Console.WriteLine();

#0061 }

#0062 System.Console.WriteLine();

#0063 }

#0004 計算document的個數

#0012~#0034 枚舉collection中所有的term

其中#0017~#0026 枚舉每個term在出現的document中的所有位置(第幾個詞,從1開始計數);#0029~#0033 計算每個term出現在哪些文檔和相應的出現頻度(即DF和TF)。

#0036~#0037在reader是SegmentReader類型的情況下有效。

#0040~#0061可以快速的讀取某篇文檔中出現的term和相應的頻度。但是這部分需要在建索引時,設置storeTermVector為true。比如

doc.Add(Field.Text("contents", reader, true));

其中的第三項即是。默認為false。

有了這些數據,就可以統計我需要的數據了。以後我會介紹如何建立索引,如何應用Lucene。

  • 上一篇:api源代碼是錯誤的
  • 下一篇:電腦打不開瀏覽器怎麽辦?
  • copyright 2024編程學習大全網