我有实体女巫用数字标识符(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。
感谢您抽出时间阅读并希望得到您的帮助。
答案 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将提取的数据添加为新字段。