Lucene 3.5自定义有效负载

时间:2012-02-03 14:53:08

标签: java lucene tokenize

使用Lucene索引,我有一个标准的文档格式,如下所示:

Name: John Doe 
Job: Plumber 
Hobby: Fishing

我的目标是将有效负载附加到作业字段,该作业字段将包含有关管道的其他信息,例如,管道文章的维基百科链接。我不想把有效载荷放在其他地方。最初,我找到了一个涵盖我想做的事情的例子,但是它使用了Lucene 2.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()之后,我将它添加到文档字段并索引文档。但是,当我打印出文档并使用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();

2 个答案:

答案 0 :(得分:1)

很难说出为什么没有保存有效负载,原因可能在于使用您提供的方法的代码。

设置有效负载的最便捷方式是TokenFilter - 我认为采用这种方法可以为您提供更清晰的代码,从而使您的方案正常运行。我认为在Lucene源中查看这种类型的过滤器是最具说明性的,例如: TokenOffsetPayloadTokenFilter。您可以在test for this class中找到如何使用它的示例。

还请考虑是否没有更好的地方来存储这些超链接而不是有效负载。有效载荷具有非常特殊的应用,例如提升一些术语取决于它们在原始文档中的位置或格式,词性......它们的主要目的是影响搜索的执行方式,因此它们通常是数值,有效地打包以减少索引大小。

答案 1 :(得分:0)

我可能会遗漏一些东西,但...... 您不需要自定义标记生成器将其他信息与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));

然后,您可以像任何其他字段一样获取“链接”字段。

此外,如果你确实需要一个自定义标记器,那么你肯定需要一个自定义分析器来实现它,用于索引构建和搜索。