将tika桥添加到FieldBridge中新定义的字段

时间:2013-05-15 10:38:24

标签: hibernate lucene hibernate-search

我有实体女巫用数字标识符(binId)指向二进制数据。实用程序类可以提供给定ID的二进制流形式。我的目标是索引这个二进制流 - 通常是一个文件。

概念是,为二进制数据标识符字段创建桥。在内部桥我将调用实用程序类,获取流并使用给定流创建新字段。然后,我希望Tika bridge对此流进行索引/分析。

我使用FieldBridge但没有LuceneOptions。另外,我无法注释实体类,因此我使用Programmatic API

到目前为止看起来像:

public class SearchMappingFactory {
    @Factory
    public SearchMapping getSearchMapping(){
        SearchMapping mapping = new SearchMapping();
        mapping.entity(Attachment.class)
            .indexed()
            .property("id", ElementType.FIELD)
            .documentId()
            .property("name", ElementType.FIELD)
            .field()
            .property("description", ElementType.FIELD)
            .field()
            .property("binId", ElementType.FIELD)
            .field()
            .name("attachmentFile")
            .bridge(AttachmentContentSearchBridge.class)
            .property("content", ElementType.FIELD)  // this is my try to define additional bridge
            .field()
            .bridge(TikaBridge.class)
        ;
        return mapping;
    };
}

和我的桥:

public class AttachmentContentSearchBridge implements FieldBridge {

    @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        Reader reader = new InputStreamReader(MyBinUtil.getStreamForId((Integer)value));
        Field field = new Field("content",reader);
//i'd like to add tika bridge here, but i cant
        document.add(field);
    }
}

让我们从桥上开始吧。这很简单,唯一的问题是,我无法定义到新创建的字段content的桥接 - 这是我得到的主要问题。

我尝试通过在映射中添加content字段来解决它,我可以在其中定义桥接。该定义被接受,我的应用程序启动并运行,但content的索引没有关键字:(

请告诉我如何为FieldBridge中创建的字段定义TikeBridge。

感谢您抽出时间阅读并希望得到您的帮助。

1 个答案:

答案 0 :(得分:0)

如果通过id和自定义util类获取流数据,则无法使用@TikaBridge注释。由于注释的文档表明它仅适用于二进制数据字段或字符串/ URL字段。在后一种情况下,String / URL用于加载二进制数据。

在你的情况下,你只需要重新实现org.hibernate.search.bridge.builtin.TikaBridge中发生的事情。

有趣的部分是:

public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
    if ( value == null ) {
        throw new IllegalArgumentException( "null cannot be passed to Tika bridge" );
    }
    InputStream in = null;
    try {
        in = getInputStreamForData( value );

        Metadata metadata = metadataProcessor.prepareMetadata();
        ParseContext parseContext = parseContextProvider.getParseContext( name, value );

        StringWriter writer = new StringWriter();
        WriteOutContentHandler contentHandler = new WriteOutContentHandler( writer );

        Parser parser = new AutoDetectParser();
        parser.parse( in, contentHandler, metadata, parseContext );
        luceneOptions.addFieldToDocument( name, writer.toString(), document );

        // allow for optional indexing of metadata by the user
        metadataProcessor.set( name, value, document, luceneOptions, metadata );
    }
    catch ( Exception e ) {
        throw propagate( e );
    }
    finally {
        closeQuietly( in );
    }
}

您需要输入数据流,然后创建一个tika解析器并将其与Tika可以写入数据的输出StringWriter一起传递给它。最后,您需要使用LuceneOptions将提取的数据添加为新字段。