Hibernate Search ClassBridge来解决附件同步索引的问题
程序员文章站
2022-04-15 23:44:41
...
我有个类 Issue,但是它的附件并不放在数据库当中,而是放在某个目录下。
这时候,我想让 hibernate search 能够自动的把这个类的附件也一并建立
索引,检索的时候能够针对附件进行检索。
刚开始用很土的办法,在 Issue类里面增加了一个 attachContent 的clob字段,
用来存放从文件中抽取出来的内容,然后在 hibernate 的 preInsert/preUpdate
拦截器当中,扫描附件文件,抽取其中的内容,然后set到 attachContent 属性中,
这样就可以达到目标了。
虽然这样已经可以工作了,但是总是感觉不好。首先,attachContent这个字段比较
恶心,完全没必要存在的,影响selct效率。其次,这个拦截器也感觉很不好,把一
个动作分散在好几个地方,而且每次update的时候都重新扫描,影响效率。
搜了一下,偶尔发现了一个 FieldBridge的接口, 就是 hibernate search里面用来对
field 进行custom索引的接口,然后又发现同一个package下面还有个 ClassBridge 的
Annotation。对 Issue 类设置 ClassBridge,然后自己做了一个类,来达到我的目标。
@Entity
@Indexed
@ClassBridge( impl = IssueClassBridge.class)
public class Issue {
IssueClassBridge 实际上是一个FieldBridge:
public class IssueClassBridge implements FieldBridge {
@Override
public void set(String name, Object obj, Document doc, Store store, Index index, Float boost) {
try {
Issue issue = (Issue) obj;
AutoDetectParser parser = new AutoDetectParser();
StringWriter writer = new StringWriter();
Metadata metadata = new Metadata();
File file = new File( issue.getAttachFilePath);
FileInputStream is = new FileInputStream( file);
parser.parse( is, new BodyContentHandler(writer), metadata);
is.close();
Field field = new Field("ALL", writer.toString() + " " + metadata.toString(), store, index);
doc.add( field);
} catch ( Throwable e) {
System.out.println( "Error: " + obj + " " + e.getMessage() );
}
}
}
其中用 lucene 的 tika 来对附件的内容和 meta信息进行抽取。这样基本上只要在 Issue类上设置一下就ok了,
没有任何其他的设置工作,比较简单。当然,还可以判断一下是否需要index,如果附件没有变化,就不用重新index了。