2011-04-10 53 views
8

我正在尋找一種方法來查找在Lucene中使用waldcard搜索在文檔中匹配的詞語。我使用解釋器來嘗試找到這些條款,但是失敗了。下面是相關代碼的一部分。在使用通配符搜索進行搜索時獲取文檔中匹配的詞彙

ScoreDoc[] myHits = myTopDocs.scoreDocs; 
int hitsCount = myHits.Length; 
for (int myCounter = 0; myCounter < hitsCount; myCounter++) 
{ 
    Document doc = searcher.Doc(myHits[myCounter].doc); 
    Explanation explanation = searcher.Explain(myQuery, myCounter); 
    string myExplanation = explanation.ToString(); 
    ... 

當我在說微*搜索,文件被發現,它進入循環,但myExplanation包含不匹配,沒有其他信息。

如何獲取本文檔中找到的術語?

任何幫助將不勝感激。

Regards

回答

8
class TVM : TermVectorMapper 
    { 
     public List<string> FoundTerms = new List<string>(); 
     HashSet<string> _termTexts = new HashSet<string>(); 

     public TVM(Query q, IndexReader r) : base() 
     { 
      List<Term> allTerms = new List<Term>(); 
      q.Rewrite(r).ExtractTerms(allTerms); 
      foreach (Term t in allTerms) _termTexts.Add(t.Text()); 
     } 

     public override void SetExpectations(string field, int numTerms, bool storeOffsets, bool storePositions) 
     { 
     } 

     public override void Map(string term, int frequency, TermVectorOffsetInfo[] offsets, int[] positions) 
     { 
      if (_termTexts.Contains(term)) FoundTerms.Add(term); 
     } 
    } 

    void TermVectorMapperTest() 
    { 
     RAMDirectory dir = new RAMDirectory(); 
     IndexWriter writer = new IndexWriter(dir, new Lucene.Net.Analysis.Standard.StandardAnalyzer(), true); 
     Document d = null; 

     d = new Document(); 
     d.Add(new Field("text", "microscope aaa", Field.Store.YES, Field.Index.ANALYZED,Field.TermVector.WITH_POSITIONS_OFFSETS)); 
     writer.AddDocument(d); 

     d = new Document(); 
     d.Add(new Field("text", "microsoft bbb", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); 
     writer.AddDocument(d); 

     writer.Close(); 

     IndexReader reader = IndexReader.Open(dir); 
     IndexSearcher searcher = new IndexSearcher(reader); 

     QueryParser queryParser = new QueryParser("text", new Lucene.Net.Analysis.Standard.StandardAnalyzer()); 
     queryParser.SetMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE); 
     Query query = queryParser.Parse("micro*"); 

     TopDocs results = searcher.Search(query, 5); 
     System.Diagnostics.Debug.Assert(results.TotalHits == 2); 

     TVM tvm = new TVM(query, reader); 
     for (int i = 0; i < results.ScoreDocs.Length; i++) 
     { 
      Console.Write("DOCID:" + results.ScoreDocs[i].Doc + " > "); 
      reader.GetTermFreqVector(results.ScoreDocs[i].Doc, "text", tvm); 
      foreach (string term in tvm.FoundTerms) Console.Write(term + " "); 
      tvm.FoundTerms.Clear(); 
      Console.WriteLine(); 
     } 
    } 
+0

必須修改TVM類以使用HashTable for C#。謝謝,因爲我想要它。 – Puneet 2011-09-24 08:53:50

+0

您無需使用Lucene.Net 2.9.4g在https://svn.apache.org/repos/asf/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src中對其進行修改 – 2011-09-24 09:09:05

4

一種方法是使用熒光筆;另一種方法是通過用適當的重寫器調用myQuery.rewrite()來重寫查詢來模仿Highlighter所做的事情;這可能更接近您嘗試的內容。這會將查詢重寫爲包含所有匹配條款的布爾查詢;你可以很容易地從這些詞中獲得這些詞。這足以讓你走了嗎?

下面是我想到的想法;抱歉,關於混淆重新:重寫查詢;這裏並沒有真正的相關性。

TokenStream tokens = TokenSources.getAnyTokenStream(IndexReader reader, int docId, String field, Analyzer analyzer); 
CharTermAttribute termAtt = tokens.addAttribute(CharTermAttribute.class); 
while (tokens.incrementToken()) { 
    // do something with termAtt, which holds the matched term 
} 
+0

其實我所尋找的是能夠得到的只有那些在文檔中找到的術語。因此,如果一個文件包含顯微鏡,而另一個包含microsoft,那麼當我在第一個文件上時,我應該只顯微鏡,當我在第二個文件上時,我應該只獲得microsoft作爲匹配的術語。你的建議會給我所有在索引字段中匹配micro *的術語。我希望我能夠解釋我在找什麼。 – Puneet 2011-09-21 12:29:16

+0

我編輯了答案 - 希望更接近你需要的東西 – 2011-09-21 13:24:56