欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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了。