2011-04-10 8 views
8

Lucene'de waldcard araması kullanarak belgede eşleşen terimleri bulmanın bir yolunu arıyorum. Açıklamaları denemek için açıklayıcıyı kullandım ama bu başarısız oldu. İlgili kodun bir kısmı aşağıdadır. Bir joker karakter araması kullanarak arama yaparken bir belgede eşleşen terimler alma

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(); 
    ... 

ben diyelim ki mikro * arama yapın

, belgeler bulunur ve döngü girmek ama myExplanation OLMAYAN KAÇINCI ve başka hiçbir bilgi içerir.

Bu belgede bulunan terimi nasıl alabilirim?

Herhangi bir yardım en çok takdir edilecektir.

Selamlar

cevap

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 sınıfını C# için HashTable'ı kullanmak zorunda kaldım. Teşekkürler istediğim gibi çalıştı. – Puneet

+0

https://svn.apache.org/repos/asf/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src adresinden Lucene.Net 2.9.4g ile değişiklik yapmanıza gerek yok. –

4

bir yolu İşaretleyici kullanmaktır; Başka bir yol, Vurgulayıcının, uygun bir yeniden yazmayla myQuery.rewrite() yöntemini çağırarak, sorgunuzu yeniden yazarak ne yaptığını taklit etmektir; Bu, çalıştığınız şeye muhtemelen daha yakındır. Bu, sorguyu tüm eşleşen Şartları içeren bir BooleanQuery'ye yeniden yazar; Bu kelimeleri kolayca kolayca alabilirsiniz. Gitmen için yeterli mi?

Aklımda olan fikir şu; karışıklık için özür dilerim: yeniden yazma sorguları; Burada gerçekten alakalı değil. Aradığım Aslında Ne

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

belgesinde bulunan tek bu terimleri elde edebilmek olmaktır. Böylece bir belge mikroskop içeriyorsa ve diğeri microsoft içeriyorsa, ilk belgede olduğumda, sadece mikroskop almalıyım ve ikinci belgede olduğumda, eşleştirilen terim olarak sadece microsoft almalıyım. Öneriniz bana endeks alanında mikro * ile eşleşecek tüm terimleri verecektir. Umarım ne aradığımı açıklayabiliyorum. – Puneet

+0

Cevabı düzenledim - umarım neye ihtiyacınız olduğuna daha da yakındır –