使用Lucene索引时,我有一个标准文档格式,如下所示:
姓名:无名氏工作:水管工霍比:钓鱼
我的目标是在工作字段中附加一个有效负载,该字段包含关于管道的其他信息,例如,指向管道文章的wikipedia链接。我不想把有效载荷放在其他地方。最初,我发现了一个包含我想要做的事情的示例,但是它使用了Lucene2.2,并且没有更新来反映令牌流api中的更改。经过进一步的研究,我想出了一个小怪物,为这个领域建立了一个定制的令牌流。
public static TokenStream tokenStream(final String fieldName, Reader reader, Analyzer analyzer, final String item) {
final TokenStream ts = analyzer.tokenStream(fieldName, reader) ;
TokenStream res = new TokenStream() {
CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
PayloadAttribute payAtt = addAttribute(PayloadAttribute.class);
public boolean incrementToken() throws IOException {
while(true) {
boolean hasNext = ts.incrementToken();
if(hasNext) {
termAtt.append("test");
payAtt.setPayload(new Payload(item.getBytes()));
}
return hasNext;
}
}
};
return res;
}
当我获取令牌流并对所有结果进行迭代时,在将其添加到字段之前,我会看到它成功地将项与有效负载配对。调用流上的reset()之后,我将其添加到document字段并对文档进行索引。但是,当我打印出文档并使用Luke查看索引时,我的自定义令牌流没有完成剪切。字段名显示正确,但令牌流中的术语值没有出现,也没有指示有效负载的成功附件。
这就引出了两个问题。首先,我是否正确地使用了令牌流,如果是的话,为什么在我将它添加到字段时它不标记呢?其次,如果我没有正确地使用流,是否需要编写我自己的分析器。使用Lucene标准分析器将这个示例拼凑在一起,生成令牌流并编写文档。如果可能的话,我想避免编写我自己的分析器,因为我只希望将有效负载附加到一个字段中!
编辑:
呼叫码
TokenStream ts = tokenStream("field", new StringReader("value"), a, docValue);
CharTermAttribute cta = ts.getAttribute(CharTermAttribute.class);
PayloadAttribute payload = ts.getAttribute(PayloadAttribute.class);
while(ts.incrementToken()) {
System.out.println("Term = " + cta.toString());
System.out.println("Payload = " + new String(payload.getPayload().getData()));
}
ts.reset();
发布于 2012-02-09 20:06:25
很难知道为什么没有保存有效负载,原因可能在于使用您提供的方法的代码。
设置有效载荷的最方便的方法是在TokenFilter
中--我认为采用这种方法将为您提供更干净的代码,从而使您的场景正确工作。我认为在Lucene源中查看这种类型的过滤器是最有说明性的,例如TokenOffsetPayloadTokenFilter
。您可以找到一个如何在这门课的考试中使用它的示例。
还请考虑是否有更好的地方存储这些超链接比在有效载荷。有效载荷有非常特殊的应用,例如,增加一些术语取决于它们在原始文档中的位置或格式,词性的一部分。它们的主要目的是影响搜索的执行方式,因此它们通常是数字值,可以有效地打包以减少索引大小。
发布于 2012-02-09 20:16:21
我可能漏掉了什么但是..。您不需要自定义令牌程序将附加信息与Lucene文档相关联。只是存储是一个未分析的领域。
doc.Add(new Field("fname", "Joe", Field.Store.YES, Field.Index.ANALYZED));
doc.Add(new Field("job", "Plumber", Field.Store.YES, Field.Index.ANALYZED));
doc.Add(new Field("link","http://www.example.com", Field.Store.YES, Field.Index.NO));
然后,您可以得到“链接”字段,就像任何其他字段一样。
另外,如果您确实需要一个自定义标记器,那么您肯定需要一个自定义分析器来实现它,用于索引构建和搜索。
https://stackoverflow.com/questions/9130577
复制相似问题