2011-07-09 67 views
3

我想弄清楚有效載荷在Lucene中的工作方式,我似乎無法理解它。 我的情況如下:Lucene 3.1有效負載

我需要索引具有單個內容字段的文檔並附加到該字段內的文本中的每個標記有效負載(大約10個字節)。我需要使用的分析儀是一個基本的空白分析儀。

從我在互聯網上閱讀的各種文章中,使用有效載荷進行工作的方法是創建我自己的分析器並在標記化步驟中附加有效載荷。我想出了下面的代碼爲我的新的自定義分析:

public TokenStream tokenStream(String fieldName, Reader reader) { 
    TokenStream tokenStream = new WhitespaceTokenizer(Version.LUCENE_31, 
      reader); 

    OffsetAttribute offsetAttribute = tokenStream 
      .getAttribute(OffsetAttribute.class); 
    CharTermAttribute termAttribute = tokenStream 
      .getAttribute(CharTermAttribute.class); 
    if (!tokenStream.hasAttribute(PayloadAttribute.class)) { 
     tokenStream.addAttribute(PayloadAttribute.class); 
    } 
    PayloadAttribute payloadAttribute = tokenStream 
      .getAttribute(PayloadAttribute.class); 

    try { 
     while (tokenStream.incrementToken()) { 
      int startOffset = offsetAttribute.startOffset(); 
      int endOffset = offsetAttribute.endOffset(); 

      String token; 

      try{ 
       token = (termAttribute.subSequence(startOffset, endOffset)).toString(); 
      } 
      catch(IndexOutOfBoundsException ex){ 
       token = new String(termAttribute.buffer()); 
      } 

      byte[] payloadBytes = payloadGenerator.generatePayload(token, 
        frequencyClassDigest); 
      payloadAttribute.setPayload(new Payload(payloadBytes)); 
     } 
     tokenStream.reset(); 

     return tokenStream; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

是我遇到的問題如下:

  1. 我不能正確讀取單個令牌。我不確定通過使用CharTermAttribute是正確的方法,但我知道它不起作用。爲了正確計算有效負載,我需要訪問單個令牌,但WithespaceTokenizer以某種方式返回粘貼在一起的單個單詞(每次3個單詞)。
  2. 我不知道是否使用PayloadAttribute是將有效載荷附加到令牌的正確方法。也許你知道另一種方式

我在哪裏可以找到一些關於如何在Lucene中實際使用Payload的好教程?我試過在網上搜索,我能找到的唯一好文章是這樣的:Lucene Payload tutorial但是它不完全符合我的需要。

謝謝

我似乎無法找到一個很好的教程

+0

您是否檢查過http://sujitpal.blogspot.com/2010/10/custom-scoring-with-lucene-payloads.html? – hkn

回答

2

您可以封裝會產生附帶通過過濾器的每個令牌的有效載荷過濾器內的有效載荷生成邏輯。我已經將Lucene的DelimitedPayloadTokenFilter模型化了。

public final class PayloadGeneratorFilter extends TokenFilter { 
    private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); 
    private final PayloadAttribute payAtt = addAttribute(PayloadAttribute.class); 
    private final PayloadGenerator payloadGenerator; 
    private final FrequencyClassDigest frequencyClassDigest; 


    public PayloadGeneratorFilter(TokenStream input, PayloadGenerator payloadGenerator, 
           FrequencyClassDigest frequencyClassDigest) { 
    super(input); 
    this.payloadGenerator = payloadGenerator; 
    this.frequencyClassDigest = frequencyClassDigest; 
    } 

    @Override 
    public boolean incrementToken() throws IOException { 
    if (input.incrementToken()) { 
     final char[] buffer = termAtt.buffer(); 
     final int length = termAtt.length(); 
     String token = buffer.toString(); 
     byte[] payloadBytes = payloadGenerator.generatePayload(token, frequencyClassDigest); 
     payAtt.setPayload(new Payload(payloadBytes)); 
     return true; 
    } 

    return false; 
    } 
} 

這將使您的分析儀的代碼很簡單:

public class NLPPayloadAnalyzer extends Analyzer { 
    private PayloadGenerator payloadGenerator; 
    private FrequencyClassDigest frequencyClassDigest; 

    public NLPPayloadAnalyzer(PayloadGenerator payloadGenerator, 
          FrequencyClassDigest frequencyClassDigest) { 
    this.payloadGenerator = payloadGenerator; 
    this.frequencyClassDigest = frequencyClassDigest; 
    } 

    public TokenStream tokenStream(String fieldName, Reader reader) { 
    TokenStream tokenStream = new WhitespaceTokenizer(Version.LUCENE_31, reader); 
    tokenStream = new PayloadGeneratorFilter(tokenStream, payloadGenerator, frequencyClassDigest); 
    return tokenStream; 
    } 
} 

另一種方法是預先處理您的有效載荷,並在發送的Lucene的,然後使用DelimitedPayloadTokenFilter文本添加他們。 text text text text 將成爲 text|1.0 text|2.2 text|0.5 text|10.5

http://sujitpal.blogspot.com/2010/10/denormalizing-maps-with-lucene-payloads.html也是一個很好的資源。

+0

+1提示DelimitedPayloadTokenFilter – Marc