我试图找出有效载荷在Lucene工作的方式,我似乎无法掌握它。我的情况如下:
我需要索引一个具有单个内容字段的文档,并为该字段内的文本中的每个令牌附加一个有效负载(约10字节)。我需要使用的分析器是一个基本的空白分析器。
从我在互联网上读到的各种文章来看,处理有效负载的方法是创建我自己的Analyzer,并在标记化步骤中附加有效负载。我为我的新自定义分析器编写了以下代码:
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;
}
}
我遇到的问题如下:
- 我不能正确读取单个令牌。我不确定通过使用CharTermAttribute是正确的方法,但我知道它只是不起作用。为了正确计算有效负载,我需要获得单个令牌,但不知怎的,WithespaceTokenizer返回粘合在一起的单个单词(一次3个单词)。
- 我不知道是否使用PayloadAttribute是将有效载荷附加到令牌的正确方法。也许你知道另一种方法
我在哪里可以找到一些关于如何在Lucene中实际使用有效负载的好教程?我试着在网上搜索,我能找到的唯一好的文章是这个:Lucene有效负载教程,但它并不完全适合我的需要。
谢谢
我似乎找不到一个好的教程
您可以将有效负载生成逻辑封装在过滤器中,该过滤器将为通过过滤器的每个令牌生成有效负载。我已经模拟了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也是一个很好的资源。