我试图弄清楚负载在 Lucene 中的工作方式,但我似乎无法掌握它。 我的情况如下:
我需要为具有单个内容字段的文档编制索引,并将有效负载(大约 10 个字节)附加到该字段中文本中的每个标记。我需要使用的分析器是一个基本的空白分析器。
根据我在 Internet 上阅读的各种文章,处理有效载荷的方法是创建我自己的分析器并在标记化步骤中附加有效载荷。我为新的自定义分析器编写了以下代码:
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 是否是正确的方法,但我知道这是行不通的。我需要获取单个 token 才能正确计算有效负载,但 WithespaceTokenizer 以某种方式返回粘合在一起的单个单词(一次 3 个单词)。
- 我不知道使用 PayloadAttribute 是否是将负载附加到 token 的正确方法。也许你知道另一种方式
我在哪里可以找到一些关于如何在 Lucene 中实际使用有效负载的好教程?我试过在网上搜索,唯一能找到的好文章是:Lucene Payload tutorial但是它并不完全符合我的需要。
谢谢
我好像找不到好的教程
最佳答案
您可以将负载生成逻辑封装在一个过滤器中,该过滤器将为通过过滤器的每个 token 生成负载。我已经根据 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|1.0 text|2.2 text|0.5 text|10.5
http://sujitpal.blogspot.com/2010/10/denormalizing-maps-with-lucene-payloads.html也是一个很好的资源。
关于java - Lucene 3.1 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6634315/