0

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在我的映射中添加字段来解决它,我可以在其中定义桥接。定义被接受,我的应用程序启动并工作,但 index forcontent没有关键字:(

请给我任何建议,如何为 FieldBridge 中创建的字段定义 TikeBridge。

感谢您花时间阅读并希望您的帮助。

4

1 回答 1

0

如果通过 id 和自定义 util 类获取流数据,则不能使用 @TikaBridge 注释。正如注释的文档所暗示的,它仅适用于二进制数据字段或字符串/URL 字段。在后一种情况下,字符串/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 解析器并将其与输出 StringWriter 一起传递给 Tika 可以将数据写入的输出。最后,您需要使用 LuceneOptions 将提取的数据添加为新字段。

于 2013-05-16T10:29:04.140 回答